0
点赞
收藏
分享

微信扫一扫

spring 使用jsontemplate 处理rest 响应内容格式

影子喵喵喵 2022-05-23 阅读 54

实际上jsontemplate只是提供了一种简化json 格式的方法,实际上我们也是可以直接基于模版引擎的

只是jsontemplate 对于json 处理相对简单,同时提供了不少方便的功能

参考图

简单的集成图,只是对于处理我们基于了jsontemplate

spring 使用jsontemplate 处理rest 响应内容格式_ide



spring 使用jsontemplate 处理rest 响应内容格式_json_02



代码集成

很简单,核心就是利用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();
}

默认实现

@Component
public class BasicTemplateStorage implements TemplateStorage {
private ConcurrentHashMap<String, String> basicStorage = new ConcurrentHashMap<>();


@Override
public String getTemplateContent(String bizID) {
String content = basicStorage.get(bizID);
return content;
}


@Override
public 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;
}


@Override
public List<String> allTemplates() {
return basicStorage.values().stream().collect(Collectors.toList());
}


@Override
public List<String> allBizIDs() {
return basicStorage.keySet().stream().collect(Collectors.toList());
}
}
  • 模版初始化
@Bean
public CommandLineRunner commandLineRunner(TemplateStorage templateStorage){


return new CommandLineRunner() {
@Override
public 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();
}



  • 效果

spring 使用jsontemplate 处理rest 响应内容格式_json_03






jsontemplate一些问题

  • 空值处理
    默认对于空值的处理是有bug的,会造成异常,我基于官方代码调整了,同时添加了一个重载函数,可以自定义处理
  • 默认null 处理


public class DefaultNullBuildHandler implements  DefaultBuildHandler{
@Override
public 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 map
if (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 template
jsonNode = 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​​


举报

相关推荐

0 条评论