ARTICLE · 1144127
轻量,动态JSON模板引擎JJTemplate
轻量,动态JSON模板引擎JJTemplate《Spring Boot 3实战案例锦集》PDF电子书已更新至130篇! 🎉🎉《Spring Boot实战案例合集》目前已更新236个案例,我们将持续不断的更新。文末有电子书目录。→ 现在就订阅合集
2.实战案例 2.1 快速入门 引入依赖 Java代码定义模板 输出结果 2.2 JJT语法 2.3 语法示例 输出 输出 输出 输出 输出 2.4 使用函数 
示例: 输出 以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏 Redis Search:比Elasticsearch快5倍
环境:Spring Boot 3.5.0
1. 简介
JJTemplate 是一款轻量级模板引擎,旨在实现最短的渲染时间,并支持与 JSON 兼容的输入/输出。JJT 代表 Java JSON Template。JJTemplate 将模板编译为优化的抽象语法树(AST),以实现快速执行,同时保证生成的结果为有效的 JSON。
<dependency><groupId>io.github.sibmaks.jjtemplate</groupId><artifactId>jjtemplate-parser</artifactId><version>1.0.2</version></dependency><dependency><groupId>io.github.sibmaks.jjtemplate</groupId><artifactId>jjtemplate-compiler</artifactId><version>1.0.2</version></dependency>
var script = TemplateScript.builder().template(Map.of("id", "{{ .id }}","name", "{{ .name }}")).build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("id", 666) ;data.put("name", "Pack_xg") ;var result = compiled.render(data);System.err.println(result) ;
{id=666, name=Pack_xg}JJT 保持 JSON 结构的可见性。四种插值形式涵盖了替换、条件插入和展开。
访问变量
从渲染上下文和定义中读取根值或嵌套值。语法:
.user.name替换
直接插入类型化的结果:布尔值仍为布尔值,数值仍为数值。语法:
{{ expression }}条件插入
当表达式计算结果为 null 时,跳过该对象的字段或数组项。语法:
{{? expression }}展开
将对象展开为对象,或将集合中的值展开为数组。语法:
{{. expression }}管道
将左侧的值传递给一个函数,并组合变换。语法:
.value | string:trim三元运算
在行内选择一个值;分支中可以包含调用、管道和嵌套表达式。语法:
.ready ? 'yes' : 'no'安全访问
当属性或匹配的方法不存在时,返回 null;将其与 default 结合使用以实现备选方案。语法:
.repository?.foo('bar')条件插入
var script = TemplateScript.builder().template(List.of("{{? .sex1 }}","{{? .sex2 }}","{{? .sex3 }}")).build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("sex1", "男") ;data.put("sex2", "女") ;data.put("sex3", null) ;var result = compiled.render(data);System.err.println(result) ;
[男, 女]展开
var script = TemplateScript.builder().template(Map.of("name", "{{? .name }}","{{. .extra }}", true)).build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("name", "Pack_xg") ;data.put("extra", Map.of("role", "admin")) ;var result = compiled.render(data);System.err.println(result) ;
{role=admin, name=Pack_xg}范围
Definition defintion = new Definition() ;defintion.put("{{ rows range item,index of .items }}", Map.of("position", "{{ .index }}", "value", "{{ .item }}")) ;var script = TemplateScript.builder().definitions(List.of(defintion)).template("{{ .rows }}").build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("items", List.of("A", "B", "C")) ;var result = compiled.render(data);System.err.println(result) ;
[{position=0, value=A},{position=1, value=B},{position=2, value=C}]
Switch
Definition defSwitch = new Definition() ;defSwitch.put("{{ message switch .status }}", Map.of("ok", "成功", "fail", "失败", "{{ else }}", "未知")) ;var script = TemplateScript.builder().definitions(List.of(defSwitch)).template("{{ .message }}").build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("status", "fail") ;var result = compiled.render(data);System.err.println(result) ;
失败安全访问
var script = TemplateScript.builder().template(Map.of("name", "{{ default .user?.name, '未知' }}")).build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("user", Map.of("name", "Pack_xg")) ;var result = compiled.render(data);System.err.println(result) ;
{name=Pack_xg} 或者 {name=未知} // 当上下文中不存在 user时函数按命名空间分组。全局逻辑函数则特意省略了命名空间。

var script = TemplateScript.builder().template(Map.of("name", "{{ .name?.substring(1) }}","hobbySize", "{{ list:len .hobbies }}","extras", "{{ map:new 'head', 'xxx', 'tail', 'ooo' }}","birth", "{{ date:parse 'yyyy-MM-dd', .birth }}","rate", "{{ math:div .left, .right }}")).build();var compiler = TemplateCompiler.getInstance();var compiled = compiler.compile(script);Map<String, Object> data = new HashMap<>() ;data.put("name", "Pack_xg") ;data.put("hobbies", List.of("足球", "篮球", "排球")) ;data.put("birth", "2026-10-05") ;data.put("left", 460) ;data.put("right", 100) ;var result = compiled.render(data);System.err.println(result) ;
{extras={head=xxx, tail=ooo},name=ack_xg,rate=4,birth=2026-10-05,hobbySize=3}
高级开发!弃用@ControllerAdvice,这种异常处理方式性能更佳
通过Spring AOP + 多线程 + 批量实现强大的智能审计功能