net.sf.json.JSONException: There is a cycle in the hierarchy!

問題:

net.sf.json.JSONException: There is a cycle in the hierarchy!
 at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)

***************************************************************************************************************************************************

在查問一些資料後,總結出解決該問題的兩種辦法,現在與大家分享一下。

其一:根據原理來解決,如果需要解析的數據間存在級聯關係,而互相嵌套引用,在hibernate中極容易嵌套而拋出net.sf.json.JSONException: There is a cycle in the hierarchy異常。

舉個例子:現在有實驗(Lib)和類別(Libtype)兩張表,每個實驗都對應着一個類別,那麼,在類別的POJO中,就會如下代碼:

 private Integer ltid; //類別ID
 private String ltype;  //類別名稱
 private Set libs = new HashSet(0);  //對應的實驗集

當我們寫如下代碼時,會報錯:

 public ActionForward execute(ActionMapping mapping, ActionForm form,  HttpServletRequest request, HttpServletResponse response){

 LibtypeDAO libtypeDAO = new LibtypeDAO();
 List<Libtype> list = libtypeDAO.findAll();
 JSONArray jsonArray = JSONArray.fromObject(list);

 return null;

}

原因很簡單,在Libtype中,有一個與List無關的屬性值,即libs,我們只需要ltid和ltype,所以報錯。

根據我在網上查找的資料,解決辦法有如下3種:

1.設置JSON-LIB讓其過濾掉引起循環的字段:

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){

  LibtypeDAO libtypeDAO = new LibtypeDAO();
  List<Libtype> list = libtypeDAO.findAll();
  JsonConfig jsonConfig = new JsonConfig();  //建立配置文件
  jsonConfig.setIgnoreDefaultExcludes(false);  //設置默認忽略
  jsonConfig.setExcludes(new String[]{"libs"});  //此處是亮點,只要將所需忽略字段加到數組中即可,在上述案例中,所要忽略的是“libs”,那麼將其添到數組中即可,在實際測試中,我發現在所返回數組中,存在大量無用屬性,如“multipartRequestHandler”,“servletWrapper”,那麼也可以將這兩個加到忽略數組中.
  JSONArray jsonArray = JSONArray.fromObject(list,jsonConfig);  //加載配置文件
  return null;

}

2.設置JSON-LIB的setCycleDetectionStrategy屬性讓其自己處理循環,省事但是數據過於複雜的話會引起數據溢出或者效率低下。

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){

LibtypeDAO libtypeDAO = new LibtypeDAO();
List<Libtype> list = libtypeDAO.findAll();
JsonConfig jsonConfig = new JsonConfig(); //建立配置文件
jsonConfig.setIgnoreDefaultExcludes(false); //設置默認忽略
jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);   //此處是亮點,不過經過測試,第2種方法有些悲劇,雖然可以使用,但其結果貌似循環數次,至於爲啥,還請高人指點。
JSONArray jsonArray = JSONArray.fromObject(list,jsonConfig); //加載配置文件
return null;

}

3.最爲原始的辦法,自己寫個JavaBean,用forEach循環,添加到List中,這個方法我看網上有人成功,我沒試,但大概過程可以寫出來,其結果正確性有待檢驗。

JavaBean:

public LibtypeForm{

int ltid;

string ltname;

}

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){

LibtypeDAO libtypeDAO = new LibtypeDAO();
List<Libtype> list = libtypeDAO.findAll();

List<LibtypeForm> formList = new ArrayList();
for(Libtype libtype : list){

LibtypeForm form = new LibtypeForm();

form.setLtid(libtype .getLtid);

form.setLtname(libtype.getLtname);

formList.add(form);

}
JSONArray jsonArray = JSONArray.fromObject(formList);
return null;

}

如果有更好的方法,還請高人指點。

.

發佈了56 篇原創文章 · 獲贊 14 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章