日期:2014-05-16 浏览次数:20513 次
private void bean(Object object) throws JSONException { this.add("{"); BeanInfo info; try { Class clazz = object.getClass(); info = ((object == this.root) && this.ignoreHierarchy) ? Introspector .getBeanInfo(clazz, clazz.getSuperclass()) : Introspector.getBeanInfo(clazz); PropertyDescriptor[] props = info.getPropertyDescriptors(); boolean hasData = false; for (int i = 0; i < props.length; ++i) { PropertyDescriptor prop = props[i]; String name = prop.getName(); Method accessor = prop.getReadMethod(); Method baseAccessor = null; //这里增加一个临时变量作为真实希望序列化的属性的accessor方法引用 if (clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1) { //如果是CGLIB动态生成的类 try { //下面的逻辑是根据CGLIB动态生成的类名,得到原本的实体类名 //例如 EntityClassName$$EnhancerByCGLIB$$ac21e这样 //的类,将返回的是EntityClassName这个类中的相应方法,若 //获取不到对应方法,则说明要序列化的属性例如hibernateLazyInitializer之类 //不在原有实体类中,而是仅存在于CGLib生成的子类中,此时baseAccessor //保持为null baseAccessor = Class.forName( clazz.getName().substring(0, clazz.getName().indexOf("$$"))) .getDeclaredMethod(accessor.getName(), accessor.getParameterTypes()); } catch (Exception ex) { log.debug(ex.getMessage()); } } else //若不是CGLib生成的类,那么要序列化的属性的accessor方法就是该类中的方法。 baseAccessor = accessor; //这个判断,根据上面的逻辑,使得仅存在于CGLIB生成子类中的属性跳过JSON序列化 if (baseAccessor != null) { //下面的JSON Annotation的获取也修改为从baseAccessor获取,这样避免了 //由于CGLIB生成子类而导致某些方法上的JSON Annotation丢失导致处理不该 //序列化的属性 JSON json = baseAccessor.getAnnotation(JSON.class); if (json != null) { if (!json.serialize()) continue; else if (json.name().length() > 0) name = json.name(); } //ignore "class" and others if (this.shouldExcludeProperty(clazz, prop)) { continue; } String expr = null; if (this.buildExpr) { expr = this.expandExpr(name); if (this.shouldExcludeProperty(expr)) { continue; } expr = this.setExprStack(expr); } if (hasData) { this.add(','); } hasData = true; Object value = accessor.invoke(object, new Object[0]); this.add(name, value, accessor); if (this.buildExpr) { this.setExprStack(expr); } } } } catch (Exception e) { throw new JSONException(e); } this.add("}"); }