JSON解析問題:net.sf.json.JSONException: There is a cycle in the hierarchy!


作者:xcbeyond
瘋狂源自夢想,技術(shù)成就輝煌!微信公眾號:《程序猿技術(shù)大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗,樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項目的研發(fā)工作,涉及架構(gòu)設(shè)計、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗。 






 


異常問題

net.sf.json.JSONException: There is a cycle in the hierarchy!
    at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:657)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:274)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
    at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
    at net.sf.json.JSONObject.setInternal(JSONObject.java:2736)
    at net.sf.json.JSONObject.setValue(JSONObject.java:1424)
    at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:699)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:274)
    at net.sf.json.JSONArray._processValue(JSONArray.java:2513)
    at net.sf.json.JSONArray.processValue(JSONArray.java:2538)
    at net.sf.json.JSONArray.addValue(JSONArray.java:2525)
    at net.sf.json.JSONArray._fromCollection(JSONArray.java:1056)
    at net.sf.json.JSONArray.fromObject(JSONArray.java:123)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:240)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
    at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
    at net.sf.json.JSONObject.setInternal(JSONObject.java:2736)
    at net.sf.json.JSONObject.setValue(JSONObject.java:1424)
    at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:699)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:274)
    at net.sf.json.JSONArray._processValue(JSONArray.java:2513)
    at net.sf.json.JSONArray.processValue(JSONArray.java:2538)
    at net.sf.json.JSONArray.addValue(JSONArray.java:2525)
    at net.sf.json.JSONArray.element(JSONArray.java:1724)
    at net.sf.json.JSONArray.add(JSONArray.java:1249)
    at net.sf.json.JSONArray.add(JSONArray.java:1245)

原因分析

由于JSONObject內(nèi)部會無限拆解你傳入的對象,直到?jīng)]有可拆解為止,在解析bean時,出現(xiàn)死循環(huán)調(diào)用,即:多個Bean之間出現(xiàn)了相互調(diào)用。如果你傳入的對象有外鍵關(guān)系,或者相互引用,那么內(nèi)部就會死循環(huán),也就會拋出這個異常解決辦法。例如,使用Hibernate時,查詢中對象存在多表依賴關(guān)聯(lián)。
解決方法

結(jié)果數(shù)據(jù)中過濾去掉bean中引起死循環(huán)調(diào)用的屬性:

List<DataObject> list= this.baseService.find(xxx); // 結(jié)果數(shù)據(jù)list DataObject:數(shù)據(jù)對象
       
// 自定義JsonConfig用于過濾Hibernate配置文件所產(chǎn)生的遞歸數(shù)據(jù)   
JsonConfig config = new JsonConfig();
config.setExcludes(new String[]{"a","b"}); // 指定過濾哪些字段、對象
JSONArray result = JSONArray.fromObject(list, config);