jQuery調(diào)用JSON時(shí),net.sf.json.JSONException: There is a cycle in the hierarchy!
遇到了一些問題,如hibernate延遲加載錯(cuò)誤,這都是老掉牙的問題了,一看就知道加個(gè)lazy=flase就OK了。想不到快要完成了又遇到了新的問題,JSON死循環(huán),實(shí)在讓人郁悶。異常如下:
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:674)
at net.sf.json.JSONObject.fromObject(JSONObject.java:181)
at net.sf.json.JSONArray._processValue(JSONArray.java:2381)
at net.sf.json.JSONArray.processValue(JSONArray.java:2412)
Truncated. see log file for complete stacktrace
>
仔細(xì)查了一下發(fā)現(xiàn)是hibernate主外鍵關(guān)聯(lián)的錯(cuò),后來就想下json源代碼下來看,發(fā)現(xiàn)大費(fèi)周章都沒搞到j(luò)son源碼,還是老辦法反編譯瞅瞅,發(fā)現(xiàn)JSONArray根據(jù)判斷取得的不同類型調(diào)用相應(yīng)的方法,
if (object instanceof Collection)
return _fromCollection((Collection)object, jsonConfig);
而我從hibernate那得到的是list,所以去調(diào)用了_fromCollection方法,而里面的方法發(fā)現(xiàn)一個(gè)問題:該方法會(huì)不斷的拆開實(shí)體屬性,直到?jīng)]有為止,而我的ContactGroup里有兩個(gè)屬性用于自身關(guān)聯(lián)
private Set contactGroups = new HashSet(0);
private Set contactGroupPersons = new HashSet(0);
也就是說主外鍵自身關(guān)聯(lián)的是個(gè)死循環(huán),那怎么才能不讓他出現(xiàn)這種情況呢,應(yīng)該有個(gè)配置的參數(shù)后者終止循環(huán)的地方吧,查看發(fā)
現(xiàn),jsonConfig,呵呵,config應(yīng)該是配置參數(shù)吧,參看JsonConfig看見巨多的屬性,有點(diǎn)暈PropertyFilter
,不提了,看了老半天,發(fā)現(xiàn)了一個(gè)屬性PropertyFilter,PropertyFilter 是一個(gè)interface,代碼如下:
public interface PropertyFilter
{
public abstract boolean apply(Object obj, String s, Object obj1);
}
也就是說我可以通過這個(gè)方法過濾掉List里的相應(yīng)屬性,只要讓它返回true就可過濾掉,……,有點(diǎn)懸……我們重寫一下這個(gè)方法:
JsonConfig cfg = new JsonConfig();
cfg.setJsonPropertyFilter(new PropertyFilter()
{
public boolean apply(Object source, String name, Object value) {
if(name.equals("contactGroups")||name.equals("contactGroupPersons")) {
return true;
} else {
return false;
}
}
});
將hibernate產(chǎn)生的實(shí)體bean中的contactGroups和contactGroupPersons過濾掉就OK了!
然后調(diào)用JSONArray.fromObject(mychildren,cfg); mychildren是hibernate返回的list。
1
List<ShoppingCart> listCarts = sCartServiceImpl
2
.ShoppingCartTable(shoppingCart);
3
// 先過濾對(duì)set集合的拆解
4
JsonConfig config = new JsonConfig();
5
config.setJsonPropertyFilter(new PropertyFilter()
{
6
@Override
7
public boolean apply(Object arg0, String arg1, Object arg2)
{
8
if (arg1.equals("shoppingCarts"))
{
9
return true;
10
} else
{
11
return false;
12
}
13
}
14
});
15
// 將數(shù)據(jù)轉(zhuǎn)換成Json數(shù)據(jù)
16
JSONArray jsonObject = JSONArray.fromObject(listCarts, config);
17
System.out.println(jsonObject.toString());
18
搞了一下午,參考網(wǎng)絡(luò)的資料!解決問題了!