错误警告信息描述:
net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:769) Property 'handler' of class com.vrv.cems.mgr.domain.Manager_$$_javassist_182 has no read method. SKIPPED
问题分析:
JsonUtil.bean2Json(queryHistogramVO,new String[]{}));将VO对象转换成JSON对象格式jsonUtil包路径:queryHistogramVO 对象的属性和方法:public class HistogramVO { private Integer userNum; private Integer topCategory; private Integer lastUserNum; public Integer getCurrentUser() { return this.userNum; } public Integer getTopCategory() { return topCategory; } public void setTopCategory(Integer topCategory) { this.topCategory = topCategory; } public void setUserNum(Integer userNum) { this.userNum = userNum; } public Integer getLastUserNum() { return lastUserNum; } public void setLastUserNum(Integer lastUserNum) { this.lastUserNum = lastUserNum; } }
肉眼看上去这个类没有任何问题,仔细观察发现 属性"userNum"的get方法为"getCurrentUser()"
详细分析:
1、jsonutil调用类图分析:
JsonUtil工具类是通过JSONObject.fromObject()方法转换的,查看源码,对fromObject详细分析发现代码:
//这一句话很关键下面详细讲解 PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors( bean ); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); Class beanClass = bean.getClass(); for( int i = 0; i < pds.length; i++ ){ String key = pds[i].getName(); if( exclusions.contains( key ) ){ continue; } if( jsonConfig.isIgnoreTransientFields() && isTransientField( key, beanClass ) ){ continue; } Class type = pds[i].getPropertyType(); //判断如果类的get方法存在则设置属性值 if( pds[i].getReadMethod() != null ){ //--------------中间的代码省略掉 setValue( jsonObject, key, value, type, jsonConfig ); }else{ //当get方法不存在报警告错误 String warning = "Property '" + key + "' has no read method. SKIPPED"; fireWarnEvent( warning, jsonConfig ); log.warn( warning ); } }
PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors( bean );
这段代码是获取Bean所有的属性信息并将他封装成 PropertyDescriptor描述类。
深入 getPropertyDescriptors()分析:
if (beanClass == null) { throw new IllegalArgumentException("No bean class specified"); } // Look up any cached descriptors for this bean class PropertyDescriptor[] descriptors = null; descriptors = (PropertyDescriptor[]) descriptorsCache.get(beanClass); if (descriptors != null) { return (descriptors); } // Introspect the bean and cache the generated descriptors BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(beanClass); } catch (IntrospectionException e) { return (new PropertyDescriptor[0]); } descriptors = beanInfo.getPropertyDescriptors(); if (descriptors == null) { descriptors = new PropertyDescriptor[0]; }
上面是关键部分,他是通过java内省机制获取Bean的属性方法,并返回BeanInfo类。
获取属性的规则:
1、类中包含 公有get方法如: public String getCurrUser()
2、类中包含公有的 set方法如:public void setName(String c)
通过上面的分析,HistogramVO类有setUserNum()方法确没有对应的getUserNum()方法导致报""json.JSONObject - Property 'userNum' has no read method. SKIPPED"警告错误。
添加getUserNum()方法即解决问题。