問(wèn)題描述
今天在用postMan測(cè)試接口時(shí),出現(xiàn)了下面這樣的數(shù)據(jù)

出現(xiàn)這個(gè)問(wèn)題的原因是因?yàn)橹貜?fù)引用、循環(huán)引用導(dǎo)致的。對(duì)于什么是重復(fù)引用以及循環(huán)引用,這里有一篇博文寫(xiě)的很好:https://blog.csdn.net/z714359830/article/details/51527066
我就卡卡西一份說(shuō)明過(guò)來(lái),一起參考
什么是重復(fù)/循環(huán)引用
簡(jiǎn)單說(shuō),重復(fù)引用就是一個(gè)集合/對(duì)象中的多個(gè)元素/屬性同時(shí)引用同一對(duì)象,循環(huán)引用就是集合/對(duì)象中的多個(gè)元素/屬性存在相互引用導(dǎo)致循環(huán)。
舉例說(shuō)明
- 重復(fù)引用
List<Object> list = new ArrayList<>();
Object obj = new Object();
list.add(obj);
list.add(obj);
- 循環(huán)引用
// 循環(huán)引用的特殊情況,自引用
Map<String,Object> map = new HashMap<>();
map.put("map",map);
//
// map1引用了map2,而map2又引用map1,導(dǎo)致循環(huán)引用
Map<String,Object> map1 = new HashMap<>();
Map<String,Object> map2 = new HashMap<>();
map1.put("map",map2);
map2.put("map",map1);
循環(huán)引用會(huì)觸發(fā)的問(wèn)題
重復(fù)引用問(wèn)題不是很大,但是循環(huán)引用的問(wèn)題就很?chē)?yán)重
一般來(lái)說(shuō),存在循環(huán)引用問(wèn)題的集合/對(duì)象在序列化時(shí)(比如Json化),如果不加以處理,會(huì)觸發(fā)StackOverflowError(棧內(nèi)存溢出)異常。
分析原因:
當(dāng)序列化引擎解析map1時(shí),它發(fā)現(xiàn)這個(gè)對(duì)象持有一個(gè)map2的引用,轉(zhuǎn)而去解析map2。解析map2時(shí),發(fā)現(xiàn)他又持有map1的引用,又轉(zhuǎn)回map1。如此產(chǎn)生StackOverflowError異常。
所以大家還是要謹(jǐn)慎對(duì)待的
解決方式
FastJson提供了SerializerFeature.DisableCircularReferenceDetect這個(gè)序列化選項(xiàng),用來(lái)關(guān)閉引用檢測(cè)
如果是重復(fù)引用,且確定是安全的寫(xiě)法,那么解決方案有兩種:
- 局部關(guān)閉FastJson的引用檢測(cè)(推薦)
返回結(jié)果集的使用,用JSON.parseArray或者JSON.parseObject轉(zhuǎn)換一下結(jié)果集
JSON.parseArray(JSON.toJSONString(objects, SerializerFeature.DisableCircularReferenceDetect), Object.class);
- 全局關(guān)閉FastJson的引用檢測(cè)(不推薦)
在config類(lèi)配置文件中,加入
fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);