实际上jsontemplate只是提供了一种简化json 格式的方法,实际上我们也是可以直接基于模版引擎的
只是jsontemplate 对于json 处理相对简单,同时提供了不少方便的功能
参考图
简单的集成图,只是对于处理我们基于了jsontemplate


代码集成
很简单,核心就是利用jsontemplate 函数,然后传入数据,返回数据就可以了
- maven 依赖
主要此版本是我自定义开发的,因为默认的对于处理不存在的变量是有问题的,具体代码参考github
<dependency><groupId>com.github.json-template</groupId><artifactId>jsontemplate</artifactId><version>0.2.2</version></dependency>- 简单模版存储包装
实际使用可以基于配置中心,基于本地的推荐基于cache 管理 - 模版存储接口
public interface TemplateStorage {String getTemplateContent(String bizID);Boolean putTemplate(String bizID,String templateContent) throws Exception;List<String> allTemplates();List<String> allBizIDs();}默认实现
@Componentpublic class BasicTemplateStorage implements TemplateStorage {private ConcurrentHashMap<String, String> basicStorage = new ConcurrentHashMap<>();@Overridepublic String getTemplateContent(String bizID) {String content = basicStorage.get(bizID);return content;}@Overridepublic Boolean putTemplate(String bizID, String templateContent) throws Exception {if (Strings.isNullOrEmpty(bizID)) {throw new Exception("bizid can't be null");}if (Strings.isNullOrEmpty(templateContent)) {throw new Exception("templateContent can't be null");}basicStorage.put(bizID,templateContent);return true;}@Overridepublic List<String> allTemplates() {return basicStorage.values().stream().collect(Collectors.toList());}@Overridepublic List<String> allBizIDs() {return basicStorage.keySet().stream().collect(Collectors.toList());}}- 模版初始化
@Beanpublic CommandLineRunner commandLineRunner(TemplateStorage templateStorage){return new CommandLineRunner() {@Overridepublic void run(String... args) throws Exception {templateStorage.putTemplate("alert","{\n" +" name:$name,\n" +" age:$age,\n" +" version:$name1,\n" +" appdemo:$demoapp,\n" +" rong:@s($demoapp),\n" +" userinfo:$appconfs\n" +"}");templateStorage.putTemplate("warning","{\n" +" name:$name,\n" +" age:$age,\n" +" userinfo:$appconfs\n" +"}");}};}- 接口集成
@GetMapping(value = {"/t/{type}"},produces = {"application/json"})public Object jsonTemplate(@PathVariable(value = "type") String type){List<AppConf> appConfs = new ArrayList<>();AppConf appConf = new AppConf();appConf.setAge(33222);appConf.setName("appconf");appConfs.add(appConf);AppConf appConfv2 = new AppConf();appConfv2.setAge(33222);appConfv2.setName("appconf");appConfs.add(appConfv2);MyUser myUser = new MyUser();myUser.setAge(333);myUser.setAppconfs(appConfs);myUser.setName("demoapp");JsonTemplate jsonTemplate = new JsonTemplate(templateStorage.getTemplateContent(type),new DefaultNullBuildHandler());Map context = objectMapper.convertValue(myUser,Map.class);System.out.println(context.toString());return jsonTemplate.withVars(context).prettyString();}- 效果

jsontemplate一些问题
- 空值处理
默认对于空值的处理是有bug的,会造成异常,我基于官方代码调整了,同时添加了一个重载函数,可以自定义处理 - 默认null 处理
public class DefaultNullBuildHandler implements DefaultBuildHandler{@Overridepublic JsonNode handle(String valueTypeName) {return JsonStringNode.of(null);}}src/main/java/com/github/jsontemplate/modelbuild/BasePropertyDeclaration.java
public void buildJsonTemplate(JsonBuilder builder,Map<String, IValueProducer> producerMap,Map<String, JsonNode> typeMap,Map<String, JsonNode> variableMap,String defaultTypeName,DefaultBuildHandler defaultHandler) {JsonNode jsonNode = null;if (isNullValue()) {jsonNode = new JsonNullNode();} else {jsonNode = findJsonNodeFromVariable(variableMap, typeSpec.getTypeName());if (jsonNode == null) {// it is not a variable, search type mapif (typeSpec.getTypeName() == null) {TypeSpec ancestorTypeSpec = findAncestorTypeSpec(defaultTypeName);this.typeSpec.setTypeName(ancestorTypeSpec.getTypeName());if (typeSpec.getSingleParam() == null) {this.typeSpec = ancestorTypeSpec;}}jsonNode = buildNodeFromProducer(producerMap);}if (jsonNode == null) {// this type is declared inside templatejsonNode = typeMap.get(this.typeSpec.getTypeName());}if (jsonNode == null) {// cannot find any matched type// 处理空值jsonNode = new JsonNullNode();defaultHandler.handle(this.typeSpec.getTypeName());}}joinNode(builder, jsonNode);}说明
基于jsontemplate 的好处是我们可以基于配置就可以处理接口生成了,简单而且修改灵活,而且jsontemplate提供的能力还是很强大的,我们可以灵活的扩展
实现一个比较方便的接口响应处理,比如apigateway 中,模版引擎也是不错的选择,而且集成好了理论上会更好的,比如aws 的网关就有用到模版引擎技术
目前不太好的地方是尽管jsontemplate 是支持基于map以及变量应用获取数据的,实际上方法很多,一种就是我们直接将pojo 扁平化,就可以转换为一个可以
直接嵌套的变量了
参考资料
https://github.com/json-template/JsonTemplate
https://github.com/rongfengliang/JsonTemplate
https://github.com/wnameless/json-flattener










