There is a cycle in the hierarchy解決辦法

信大家做過JSON相關的東西對這個異常並不陌生,這個異常是由於JSONObject插件內部會無限拆解你傳入的對象,直到沒有可拆解爲止,問題就在這,如果你傳入的對象有外鍵關係,或者相互引用,那麼內部就會死循環,也就會拋出這個異常
解決辦法,我們先說一種網上通用的:過濾
     不錯,過濾肯定會解決該問題,過濾也有兩種方法:

     一種是通過

Java代碼  收藏代碼

  1. jsonConfig.setExcludes(new String[]{"dianYuanHeSuans"})  

 該方法接受一個數組,也就是你需要過濾的字段,很簡單就能完成。
     二種是通過

Java代碼  收藏代碼

  1. jsonConfig.setJsonPropertyFilter(new PropertyFilter() {  

  2.               

  3.             @Override  

  4.             public boolean apply(Object source, String name, Object value) {  

  5.                 if(name.equals("qualityChecks")){  

  6.                     return true;  

  7.                 }  

  8.                 return false;  

  9.             }  

  10.         });  

 

這種方式,其實和第一種差不多,達到同樣的效果,也很簡單。

接下來是我主要想說的,其實這兩種方法,有種弊端

假如說我們一個User對象裏有個屬性是部門,引用的是Organzition這個對象,如果不做任何處理,調用JSONObject.fromObject方法同樣會拋出異常,如果我們通過過濾把Organzition屬性過濾了,那麼在前臺顯示的時候,將看不到有關部門的任何信息,其實需要顯示也不多,比如僅一個部門名字就可以,但是過濾掉什麼都沒有了,這個時候,很多同學會再建一個VO類來封裝前臺需要的屬性,這無疑增加了工作量和代碼的冗餘,LZ正是被該問困擾了很久,所以給出個解決辦法。

 

借用JSONObject裏的JsonValueProcessor接口,我們自己實現該接口,代碼如下:

Java代碼  收藏代碼

  1. /** 

  2.  * 解決JSONObject.fromObject拋出"There is a cycle in the hierarchy"異常導致死循環的解決辦法 

  3.  * @author LuoYu 

  4.  * @date 2012-11-23 

  5.  */  

  6. public class ObjectJsonValueProcessor implements JsonValueProcessor {  

  7.       

  8.     /** 

  9.      * 需要留下的字段數組 

  10.      */  

  11.     private String[] properties;  

  12.       

  13.     /** 

  14.      * 需要做處理的複雜屬性類型 

  15.      */  

  16.     private Class<?> clazz;  

  17.       

  18.     /** 

  19.      * 構造方法,參數必須 

  20.      * @param properties 

  21.      * @param clazz 

  22.      */  

  23.     public ObjectJsonValueProcessor(String[] properties,Class<?> clazz){  

  24.         this.properties = properties;  

  25.         this.clazz =clazz;  

  26.     }  

  27.   

  28.     @Override  

  29.     public Object processArrayValue(Object value, JsonConfig jsonConfig) {  

  30.         return "";  

  31.     }  

  32.   

  33.     @Override  

  34.     public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {  

  35.         PropertyDescriptor pd = null;  

  36.         Method method = null;  

  37.         StringBuffer json = new StringBuffer("{");  

  38.         try{  

  39.             for(int i=0;i<properties.length;i++){  

  40.                 pd = new PropertyDescriptor(properties[i], clazz);  

  41.                 method = pd.getReadMethod();  

  42.                 String v = String.valueOf(method.invoke(value));  

  43.                 json.append("'"+properties[i]+"':'"+v+"'");  

  44.                 json.append(i != properties.length-1?",":"");  

  45.             }  

  46.             json.append("}");  

  47.         }catch (Exception e) {  

  48.             e.printStackTrace();  

  49.         }  

  50.         return JSONObject.fromObject(json.toString());  

  51.     }  

  52.       

  53.       

  54. }  

      在processObjectValue這個方法裏重寫,具體請看代碼,另外在構造方法裏我給出了兩個參數,一個是需要留下來的屬性名,通過數組傳遞,另一個是一個Class<?> type,也是相關上面說到例子中的Organzition.class,是用來在後面通過該class調用java反射機制獲取屬性值,在取到相關屬值後組裝成字符串,最後通過JSONObject.fromObject來輸出,不這樣輸出會有問題,至於什麼問題,有好奇心的同學自己試試

下面是調用方法:

Java代碼  收藏代碼

  1. jsonConfig.registerJsonValueProcessor(Organzition.class,   

  2.        new ObjectJsonValueProcessor(new String[]{"orgName","orgId"},Organzition.class));  

其中,Organzition.class是你要處理的屬性類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章