背景
和一个第三方系统做数据同步,客户在本系统填写表单后,在保存时做数据同步,由于没有引入mq也没有其他异步通知,所以通过实时接口进行数据对接。数据交互格式是JSON数组,数组内的一个大对象,里面包含若干属性,一个小对象,还有一个对象集合。
问题
在调用接口时,将日志打印,发现JSON数组内的第一条大对象,里面包含的内容打印一切正常,但是当第二个对象开始,在小对象还有对象集合的时候出现了特殊符号:
$ref: "$.list[0]" 和 “$ref”:”$.children.0”
分析
刚开始以为是数据问题,但是数据库中不可能存在这种问题,然后搜索排查一下:
原来,使用fastjson会出现循环引用。
循环引用:当一个对象包含另一个对象时,fastjson就会把该对象解析成引用。
引用是通过$ref标示的,下面介绍一些引用的描述
“$ref”:”..” 上一级
“$ref”:”@” 当前对象,也就是自引用
“$ref”:”$” 根对象
“$ref”:”$.children.0” 基于路径的引用,相当于 root.getChildren().get(0)
解决办法:
自己在转JSON的时候,新增策略,使其禁止循环引用。
通过SerializerFeature.DisableCircularReferenceDetect
来消除对同一对象循环引用的问题,默认为false。
样例代码:
List<XXX> aaa= xxxxMapper.getxxxsByoId(id);
JSONArray arr = JSONArray.parseArray(JSON.toJSONString(aaa));
List<XXX> list= JSON.parseArray(convert(arr),XXX.class);
public String convert(JSONArray array){
return JSON.toJSONString(array, SerializerFeature.DisableCircularReferenceDetect);
}