`
阅读更多

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有处理这样的情况的方法。
分享到:
评论

相关推荐

    jsonplugin.jar包

    jsonplugin-0.32.jar jsonplugin.jar包

    jsonplugin

    java structs jsonplugin

    jsonplugin-0.33.jar

    然而,当安装并配置了JSONPlugin之后,Action可以直接返回一个JSON对象,这个对象将被序列化为JSON字符串,并作为HTTP响应的主体返回给客户端。 JSONPlugin的使用步骤一般包括以下几步: 1. 添加依赖:首先,你需要...

    jsonplugin-0.32.jar

    当Action执行完成后返回"json",Struts2就会调用JSONPlugin将Action的结果转换成JSON格式,并发送给客户端。 总结来说,JSONPlugin是Struts2框架的重要扩展,它提供了JSON处理的便利性,使得开发人员能够更加专注于...

    JsonPlugin

    JsonPlugin 是一个专门为游戏开发或软件工程设计的插件,其主要功能是处理 JSON(JavaScript Object Notation)数据。JSON 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在游戏开发中...

    jsonplugin插件

    JSONPlugin插件是针对Struts2.1.8框架的一个扩展,主要目的是为了方便地将Java对象转换为JSON(JavaScript Object Notation)格式的数据,以便与ExtJS这样的前端JavaScript库进行交互。在Web开发中,JSON作为一种轻...

    JSONPLUGIN源码

    通过深入学习和理解JSONPLUGIN的源码,开发者可以更好地定制JSON处理,优化性能,以及解决在实际项目中遇到的问题。此外,理解这一插件的工作原理也有助于扩展其他功能,例如增加自定义的JSON序列化策略,或是与其他...

    jsonplugin-0.31.jar

    jsonplugin-0.31.jar 使用JSON的一个架包.

    jsonplugin-0.7.jar

    struts2后台直接返回json对象,ajax开发必备

    jsonplugin-0.32.jar 1268047053905-integrated.jnlp

    1268047053905-integrated.jnlp jsonplugin-0.32.jar

    jsonplugin, 对 struts2.1.X版本jsonplugin-0.34.jar 的修改

    第一次上传,要5分,是物有所值,处理了jsonplugin 的no session的问题,并且添加了,新的注释,例如 @JSON(exclude='对象的名称') 就可以剔除 解决json与Hibernate之间的大部分问题 1.数据只取三层 2.对one-ton-many ,...

    jsonplugin源码包

    JSONPlugin是Struts2框架中的一个插件,主要用于支持AJAX和JSON的交互。这个源码包提供了深入理解Struts2框架与JSON处理机制的机会,对于想要提升Java Web开发技能,特别是对Struts2和JSON有研究需求的开发者来说,...

    json资源jsonplugin-0.33,2.1.8,2.1.6

    标题中的"jsonplugin-0.33,2.1.8,2.1.6"可能指的是一个JSON处理相关的插件的不同版本。这里,"jsonplugin-0.33"可能是该插件的基础版本,而"2.1.8.1"和"2.1.6"可能是Struts2框架中JSON插件的两个不同版本。Struts2是...

    json 最新依赖包 jsonplugin-0.34, json-lib-2.3-jdk15,ezmorph-1.0.6

    commons-beanutils-1.8.0 commons-collections-3.2 commons-lang-2.4 commons-logging-1.1 ezmorph-1.0.6 json-lib-2.3-jdk15 jsonplugin-0.34

    jsonplugin(struts2.0)

    3. **动作类(Action)的JSON处理**:在Action类中,需要标记可序列化的字段,这样当Action返回结果时,这些字段会被转换成JSON对象的属性。通常,使用`@serializable`注解或者将字段的访问级别设置为`public`即可。...

    jsonplugin+json.jar

    在Java开发环境中,当我们需要处理JSON数据时,通常会引入像json.jar这样的第三方库。这个jar包可能包含了如下的功能: 1. JSON解析:能够将JSON字符串转换为Java对象,例如JSONObject和JSONArray,这使得我们可以...

    struts2 的jar包jsonplugin-0.33.jar包

    当Action的execute方法返回"json"时,Struts2的JSON插件会自动将map转换为JSON格式,并发送到客户端。 此外,JSON插件还提供了一些高级功能,如自定义转换规则、排除某些字段、设置日期格式等。例如,通过使用`@...

    找到了jsonplugin-0.7.jar,分享下

    NULL 博文链接:https://yabar.iteye.com/blog/258693

    json-lib和jsonplugin

    在Java中,为了处理JSON,我们常常需要借助于一些库,如`json-lib`和`jsonplugin`。 `json-lib`是一个用Java实现的JSON库,它提供了一系列的方法来解析、生成、操作JSON格式的数据。这个库不仅支持基本的Java数据...

Global site tag (gtag.js) - Google Analytics