<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

    JsonPlugin在分析類結構并序列化時,對于CGLig動態生成的類也是按照一般類來看待的。這就導致了如下的問題:

    在一個應用中,某些情況下,一個服務類返回的實體并不是原有實體類的對象,而是CGLib動態生成的子類。例如使用Hibernate的時候,某些情況下DAO返回的是EntityClassName$$EnhancerByCGLIB$$ac21e這樣的類的對象。Hibernate在這個子類中添加了hibernateLazyInitializer等等的附加屬性。由于jsonplugin并不區分類和動態生成的類,所以也會試圖序列化hibernateLazyInitializer屬性,從而導致出現如下的異常:

    java.sql.SQLException: Positioned Update not supported.
     at com.mysql.jdbc.ResultSet.getCursorName(ResultSet.java:1800)

    另外,CGLIB生成的類,某些方法上的@JSON標記奇怪的丟失了。導致標記了@JSON(serialize=false)的屬性也被序列化。

    在網上查了很久沒有發現相關的文章,所以無奈就自己動手修改jsonplugin的代碼了。

    類:com.googlecode.jsonplugin.JSONWriter,修改bean()方法:

     1     private void bean(Object object) throws JSONException {
     2         this.add("{");
     3 
     4         BeanInfo info;
     5 
     6         try {
     7             Class clazz = object.getClass();
     8 
     9             info = ((object == this.root) && this.ignoreHierarchy) ? Introspector
    10                     .getBeanInfo(clazz, clazz.getSuperclass())
    11                     : Introspector.getBeanInfo(clazz);
    12 
    13             PropertyDescriptor[] props = info.getPropertyDescriptors();
    14 
    15             boolean hasData = false;
    16             for (int i = 0; i < props.length; ++i) {
    17                 PropertyDescriptor prop = props[i];
    18                 String name = prop.getName();
    19                 Method accessor = prop.getReadMethod();
    20                 Method baseAccessor = null//這里增加一個臨時變量作為真實希望序列化的屬性的accessor方法引用
    21                 if (clazz.getName().indexOf("$$EnhancerByCGLIB$$"> -1) {  //如果是CGLIB動態生成的類
    22                     try {
    23                         //下面的邏輯是根據CGLIB動態生成的類名,得到原本的實體類名
    24                         //例如 EntityClassName$$EnhancerByCGLIB$$ac21e這樣
    25                         //的類,將返回的是EntityClassName這個類中的相應方法,若
    26                         //獲取不到對應方法,則說明要序列化的屬性例如hibernateLazyInitializer之類
    27                         //不在原有實體類中,而是僅存在于CGLib生成的子類中,此時baseAccessor
    28                         //保持為null
    29                         baseAccessor = Class.forName(
    30                                 clazz.getName().substring(0,
    31                                         clazz.getName().indexOf("$$")))
    32                                 .getDeclaredMethod(accessor.getName(),
    33                                         accessor.getParameterTypes());
    34                     } catch (Exception ex) {
    35                         log.debug(ex.getMessage());
    36                     }
    37                 }
    38                 else    //若不是CGLib生成的類,那么要序列化的屬性的accessor方法就是該類中的方法。
    39                     baseAccessor = accessor;
    40 
    41                 //這個判斷,根據上面的邏輯,使得僅存在于CGLIB生成子類中的屬性跳過JSON序列化
    42                 if (baseAccessor != null) {    
    43                     
    44                     //下面的JSON Annotation的獲取也修改為從baseAccessor獲取,這樣避免了
    45                     //由于CGLIB生成子類而導致某些方法上的JSON Annotation丟失導致處理不該
    46                     //序列化的屬性
    47                     JSON json = baseAccessor.getAnnotation(JSON.class);
    48                     if (json != null) {
    49                         if (!json.serialize())
    50                             continue;
    51                         else if (json.name().length() > 0)
    52                             name = json.name();
    53                     }
    54 
    55                     //ignore "class" and others
    56                     if (this.shouldExcludeProperty(clazz, prop)) {
    57                         continue;
    58                     }
    59                     String expr = null;
    60                     if (this.buildExpr) {
    61                         expr = this.expandExpr(name);
    62                         if (this.shouldExcludeProperty(expr)) {
    63                             continue;
    64                         }
    65                         expr = this.setExprStack(expr);
    66                     }
    67                     if (hasData) {
    68                         this.add(',');
    69                     }
    70                     hasData = true;
    71 
    72                     Object value = accessor.invoke(object, new Object[0]);
    73                     this.add(name, value, accessor);
    74                     if (this.buildExpr) {
    75                         this.setExprStack(expr);
    76                     }
    77                 }
    78             }
    79         } catch (Exception e) {
    80             throw new JSONException(e);
    81         }
    82 
    83         this.add("}");
    84     }

    這樣修改之后,原有類中不能存在的屬性將不會被序列化,同時,由于不檢查生成的類的方法上的JSON標記,而是檢查原有類上的標記,這樣避免了由于CGLIB導致的Annotation丟失的問題。

    在此依然向諸位詢問是否JSONPlugin有處理這樣的情況的方法。
    posted on 2008-05-28 18:26 蘆葦 閱讀(1787) 評論(1)  編輯  收藏 所屬分類: Struts

    Feedback

    # re: 當JsonPlugin遇到CGLib 2009-09-22 22:33 林浩新
    JSONConfig jsonConfig=new JSONConfig();
    jsonConfig.setExcludes(new String[]{'hibernateLazyInitializer'});
    JSONObject jo=JSONObject.fromObject(user,jsonConfig);
    這樣可以解決掉這個問題  回復  更多評論
      

    主站蜘蛛池模板: 亚洲一区二区三区国产精品| 亚洲娇小性xxxx色| 国产成人免费高清激情明星| 亚洲色欲啪啪久久WWW综合网| 亚洲国产综合精品中文字幕| 最刺激黄a大片免费网站| 日韩在线视精品在亚洲| 亚洲va无码专区国产乱码| 美女视频黄是免费的网址| 日韩在线观看免费| 久久精品国产亚洲AV无码偷窥| 在线观看成人免费视频| 国产日韩AV免费无码一区二区三区| 中文字幕亚洲色图| 亚洲第一网站男人都懂| 国产乱子精品免费视观看片| 久久久久久噜噜精品免费直播| 久久亚洲国产最新网站| 图图资源网亚洲综合网站| 亚洲?V无码乱码国产精品| 真人做A免费观看| 免费看少妇高潮成人片| 国产精品亚洲а∨无码播放不卡| 中文字幕亚洲色图| 久久精品国产69国产精品亚洲| 国产精品二区三区免费播放心| 亚洲无砖砖区免费| 国产午夜无码精品免费看| 黄色三级三级免费看| 亚洲黄页网在线观看| 亚洲天堂一区二区三区| 久久精品国产精品亚洲精品 | 老色鬼久久亚洲AV综合| 精品国产亚洲男女在线线电影 | 精品亚洲视频在线| 亚洲影视自拍揄拍愉拍| 精品亚洲成a人片在线观看少妇| 亚洲色偷偷综合亚洲AV伊人| 国产乱子伦片免费观看中字| 野花高清在线观看免费完整版中文| 日本免费中文字幕|