JSONUtil.bean2Json()报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;
}

/**
* @return the topCategory
*/
public Integer getTopCategory() {
return topCategory;
}

/**
* @param topCategory the topCategory to set
*/
public void setTopCategory(Integer topCategory) {
this.topCategory = topCategory;
}

/**
* @param userNum the userNum to set
*/
public void setUserNum(Integer userNum) {
this.userNum = userNum;
}

/**
* @return the lastUserNum
*/
public Integer getLastUserNum() {
return lastUserNum;
}

/**
* @param lastUserNum the lastUserNum to set
*/
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];
}Introspector.getBeanInfo(beanClass);

上面标红的地方是关键部分,他是通过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()方法即解决问题。

总结:

这个问题虽然不是很复杂但是把Java的内省机制弄明白了。

相关文档:

http://java.sun.com/products/javabeans/docs/index.html

http://blog.youkuaiyun.com/hahalzb/archive/2010/10/28/5972421.aspx


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/liulin_good/archive/2010/12/11/6069797.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值