Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/shoucheng3/jstachio__jstachio_cve-2023-33962_1-0-0
通用工具静态代码分析 (SAST)代码分析Web安全学习与教育
GitHubshoucheng3/jstachio__jstachio_cve-2023-33962_1-0-0

jstachio__jstachio_CVE-2023-33962_1-0-0

类型安全的Java Mustache模板引擎,具备编译时模板验证、静态值绑定以及可扩展的HTML及其他内容类型转义功能。

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
311个月前尚未审核

Maven Central Github

jstachio

一个类型安全的 Java Mustache 模板引擎。

模板被编译成可读的 Java 源代码,值绑定在编译时静态检查。

文档

  • 最新 SNAPSHOT 版本 JStachio 文档
  • 当前发布版 JStachio 文档

该文档也位于 javadoc.io,但不像上面那样聚合。聚合的 javadoc 是首选的文档形式,本 README 的其余部分主要用于 宣传 营销目的。

对于之前的版本:

root@kitploit:~
https://jstach.io/doc/jstachio/VERSION/apidocs

其中 VERSION 是你想要的版本号。

为什么选择 JStachio

详见 why_jstachio_is_better.md。

特性

  • 无逻辑 Mustache (v 1.3) 语法。

    • 完全支持非可选的 Mustache 规范 v1.3.0 要求(包括空白)
    • 可选的继承支持,但有一些注意事项
    • 可选的 Lambda 支持,但由于静态特性存在一些差异
  • 今天就能获得类似 JEP 430 的支持,而且更加强大。

  • 模板编译成 Java 代码

  • 值绑定在编译时静态检查。

  • 方法、字段和 getter 方法可以在模板中引用。

  • 带有上下文信息的友好错误消息。

  • 零配置。无需插件或调整。一切都在标准 javac 下完成,兼容任何 IDE 和/或构建系统。

  • 支持非 HTML 模板。支持的转义内容类型集是可扩展的。

  • 通过 Mustache 继承规范支持布局。

  • 通过 ServiceLoader 提供回退渲染服务扩展点

    • 无缝回退到基于反射的运行时渲染,通过 JMustache 和 mustache.java(对于开发和在实时更改模板时很有用)
    • 如果你不喜欢生成的代码,仍然可以使用 JStachio 对你的 Mustache 模板进行类型检查。
  • 自定义允许输出的类型,否则会产生编译错误(避免在不友好 toString 的类上调用 toString)。

  • 用于变量运行时自定义 toString 的格式化器

  • 向生成的代码添加额外的 implements 接口,以实现类似 trait 的附加功能(@JStacheInterfaces)

  • 强大的 Lambda 支持

  • 支持 Map<String, ?>

  • 支持 Optional<?>

  • 与 JMustache 和 Handlebars 列表索引扩展兼容(如 -first、、)

性能

本项目不以成为最快的 Java 模板引擎为目标!

(不过它目前是我所知道的、在本 README 上次更新时最快的)

虽然模板语言中性能并不是那么重要(它很少成为瓶颈),但 JStachio 非常快:

https://github.com/agentgt/template-benchmark

字符串输出

模板比较

带有扩展字符的 UTF-8 字节输出

模板比较

快速示例

root@kitploit:~

@JStache(template = """
        {{#people}}
        {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old!
        {{#-last}}
        That is all for now!
        {{/-last}}
        {{/people}}
        """)
public record HelloWorld(String message, List<Person> people) implements AgeLambdaSupport {
}

public record Person(String name, LocalDate birthday) {
}

public record AgeInfo(long age, String date) {
}

public interface AgeLambdaSupport {

    @JStacheLambda
    default AgeInfo ageInfo(Person person) {
        long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now());
        String date = person.birthday().format(DateTimeFormatter.ISO_DATE);
        return new AgeInfo(age, date);
    }

}

@Test
public void testPerson() throws Exception {
    Person rick = new Person("Rick", LocalDate.now().minusYears(70));
    Person morty = new Person("Morty", LocalDate.now().minusYears(14));
    Person beth = new Person("Beth", LocalDate.now().minusYears(35));
    Person jerry = new Person("Jerry", LocalDate.now().minusYears(35));
    String actual = JStachio.render(new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)));
    String expected = """
            Hello alien Rick! You are 70 years old!
            Hello alien Morty! You are 14 years old!
            Hello alien Beth! You are 35 years old!
            Hello alien Jerry! You are 35 years old!
            That is all for now!
                            """;
    assertEquals(expected, actual);

}

安装

Maven

root@kitploit:~
<properties>
    <io.jstach.version>0.6.0-SNAPSHOT</io.jstach.version>
</properties>
...
<dependencies>
    <dependency>
        <groupId>io.jstach</groupId>
        <artifactId>jstachio</artifactId>
        <version>${io.jstach.version}</version>
    </dependency>
</dependencies>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>17</source> <!-- 17 是最低版本 -->
                <target>17</target> <!-- 17 是最低版本 -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>io.jstach</groupId>
                        <artifactId>jstachio-apt</artifactId>
                        <version>${io.jstach.version}</version>
                    </path>
                    <!-- 其他注解处理器 -->
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

注意:注解 jar (jstachio-annotation) 会间接引入

Gradle

root@kitploit:~
dependencies {
 
    implementation 'io.jstach:jstachio:VERSION'
 
    annotationProcessor 'io.jstach:jstachio-apt:VERSION'
}

示例

user.mustache

root@kitploit:~
{{#name}}
<p>Name: {{.}}, Name Length is {{length}}</p>
{{/name}}

<p>Age: {{  age  }}</p>

<p>Achievements:</p>

<ul>
{{#array}}
  <li>{{.}}</li>
{{/array}}
</ul>

{{^array}}
<p>No achievements</p>
{{/array}}

<p>Items:</p>

<ol>
{{#list1}}
  <li>{{value}}</li>
{{/list1}}
</ol>

User.java

以下类可用于提供实际数据来填充上述模板。

root@kitploit:~
@JStache(
    // 指向 src/main/resources/user.mustache 文件
    path = "user.mustache",
   
    // 或者你也可以内联模板
    template = "", 

    )
public record User(String name, int age, String[] array, List<Item<String>> list) {

   public static class Item<T> {
        private final T value;
        public Item(T value) {
            this.value = value;
        }
        T value() {
            return value;
        }
    }
}

渲染

使用上述代码,将自动生成新类 UserRenderer。此类可用于渲染填充了实际数据的模板。要渲染模板,可以使用以下代码:

root@kitploit:~
class Main {
    public static void main(String[] args) throws IOException {
        User user = new User("John Doe", 21, new String[] {"Knowns nothing"}, list);
        StringBuilder appendable = new StringBuilder();
        JStachio.render(user, appendable);
    }
}

运行此代码的结果将是

root@kitploit:~
<p>Name: John Doe, Name Length is 8</p>

<p>Age: 21</p>

<p>Achievements:</p>

<ul>
  <li>Knowns nothing</li>
</ul>

<p>Items:</p>

<ol>
  <li>helmet</li>
  <li>shower</li>
</ol>

引用不存在的字段或具有不可渲染类型的字段,都会导致编译时错误。这些错误会在项目的编译时报告,同时也会报告 Java 源代码中的其他可能错误。

root@kitploit:~
target/classes/user.mustache:5: error: Field not found in current context: 'age1'
  <p>Age: {{  age1  }} ({{birthdate}}) </p>
                  ^
  symbol: mustache directive
  location: mustache template
root@kitploit:~
target/classes/user.mustache:5: error: Unable to render field: type error: Can't render data.birthdate expression of java.util.Date type
  <p>Age: {{  age  }} ({{birthdate}}) </p>
                                    ^
  symbol: mustache directive
  location: mustache template

更多示例请参见 test/examples 项目。

Java 特定扩展

枚举匹配支持

枚举本质上具有布尔键,即枚举的名称(Enum.name()),可用作条件节。

假设 light 是一个枚举,例如:

root@kitploit:~
public enum Light {
  RED,
  GREEN,
  YELLOW
}

你可以像模式匹配一样根据枚举进行条件选择:

root@kitploit:~
{{#light.RED}}
STOP
{{/light.RED}}
{{#light.GREEN}}
GO
{{/light.GREEN}}
{{#light.YELLOW}}
Proceeed with caution
{{/light.YELLOW}}

索引支持

JStachio 与 handlebars 和 JMustache 的迭代节索引键兼容。

  • -first 是一个布尔值,当你在第一个项目时为真
  • -last 是一个布尔值,当你在可迭代对象的最后一个项目时为真
  • -index 是一个从 1 开始的索引。第一个项目将是 1 而不是 0

Lambda 支持

JStachio 以类似于 JMustache 的方式支持 Lambda 节调用。只需用 @JStacheLambda 标记你的方法,返回的模型将用于渲染 Lambda 节的内容。上下文栈的顶部可以传递给 Lambda。

与规范不同,JStachio 不支持返回动态模板然后针对上下文栈进行渲染。但是,调用方可以通过更改 Lambda 节的内容来实现动态输出,因为该节的内容充当内联模板。

设计

这个想法是创建一个模板引擎,结合 mustache 无逻辑哲学与 Java 的单一职责和静态类型。完全的编译时语法和数据绑定检查是主要要求。

目前,模板会生成 Java 代码。生成的 Java 代码应始终能编译通过。如果无法从某个模板生成有效的 Java 代码,则应生成友好的编译时错误,指向模板文件。用户不应看到生成的 Java 代码。

原始 mustache 使用 Javascript 对象来定义渲染上下文。所选 Javascript 对象的字段与模板字段绑定。

静态 mustache 使用 Java 对象来定义渲染上下文。模板字段的绑定在编译时定义并检查。缺失字段为编译时错误。

许可证

JStachio 采用 BSD 3-Clause 许可证。

下载工具
-last
-index
  • 它是迄今为止最快的类 Java Mustache 模板引擎,并且通常是速度最快的之一。

  • 除 JStachio 自身外零依赖

  • 还有一个绝对零运行时依赖的选项(即生成所有所需代码,甚至运行时也不需要 jstachio)。无需使用 Maven shade 来处理注解处理器和其他零依赖项目。对于 Graal VM 原生项目也很有用,以尽可能减小体积。

  • 对 Spring 框架的一流支持(即项目本身会提供插件,而不是依赖辅助项目)