【Java】给org.json 添加 json转Bean的方法

【引言】最近才接触到org.json,他比较小巧没有依赖包用起来还不错,不足的是没有一个JSONObject对象直接转JavaBean的方法。为了弥补这个缺憾,自己在源码中(org.java.JSONObject.java)加了一个这样的方法,这里分享一下。


昨天才知道Android系统里也有一个org.json,它里面没有JSONObject(Object bean)方法。推荐看看https://github.com/douglascrockford/JSON-java这里的源码,比Android自带的org.json功能多一点。


在JSONObject中,用了一个域

private final Map<String, Object>map;

如果一个JSONObject是由Bean转换来的,那么Bean中所有的域都被妥善存放在map中。构造函数

public JSONObject(Object bean) {
    this();
    this.populateMap(bean);
}

就是用来干这个事情的。遗憾的是并没有一个反向的方法从JSONObctive对象生成Bean对象。观察源码中populateMap(bean)方法的实现,可以看到:他是用反射实现对Bean中getter的调用。所以反过来我们遍历Map,然后用反射调用setter就能达到目标。

  • 从Bean中找出所有的域

Method[]beanMethods = javaBeanClazz.getDeclaredMethods();

  • 从Bean中找出所有的域

for (Methodmethod :beanMethods)
{
    if (method.getName().startsWith("set"))
    {

     。。。

    }

}

  • 反射调用setter method.invoke(javaBean,newObject[] {map.get(field)});

  • 方法定义的时候得耍几个小技巧

首先,populateMap方法的参数是个对象,而我们实现JSONToBean的时候,只想通过方法返回一个Bean对象,入参只说明Bean对象的Class。

其次,入参和返回值都是相同的Class,自然想到使用泛型。需要注意的是,只有泛型是无法实例化的,需要用该泛型指定一个Class对象。

所以,方法的声明看起来像这样:

public <T> TtoJavaBean(Class<T> javaBeanClazz)


【caution】

Bean中不能有Date对象这种没法串行化的域,毕竟我们是在接收端用String生成的JSONObject,Date.toString()出来的东西没法反向生成Date,想必大家都知道。

【调用】假如你有一个Bean类叫Book,然后你从服务端收到一个jsonString,现在可以直接转出Book对象

JSONObject jObject = new JSONObject(jsonString);

Book resultBook = jObject.toJavaBean(Book.class);


【代码】最后贴出完整代码,欢迎各种拍砖。

/**
     * change the JSONObject to Bean
     * 
     *  @author Y.T
     *  @param javaBeanClazz
     *          indicate target class
     *  @return JavaBean
     *  @throws JSONException
     *             any error happened during transform
     */
    public <T> T toJavaBean(Class<T> javaBeanClazz) 
    		throws JSONException {
    	Method[] beanMethods = javaBeanClazz.getDeclaredMethods();
    	T javaBean = null;

		try {
			javaBean = javaBeanClazz.newInstance();
		} catch (Exception e){
			throw new JSONException("Can not create a instance of Class "
										+ javaBeanClazz.getName() + ".");
		}
    	for (Method method : beanMethods)
    	{
    		if (method.getName().startsWith("set"))
    		{
                String field = method.getName();
                field = field.substring(field.indexOf("set") + 3);
                field = field.toLowerCase().charAt(0) + field.substring(1);
                //ignore the null value exception, add by y.t. 2015.03.10
                if (map.get(field)==null)
                {
                	continue;
                }
                try {
					method.invoke(javaBean, new Object[] {map.get(field)});
				} catch (Exception e) {
					// TODO Auto-generated catch block
					throw new JSONException("Can not find property"
							+ " setter for field \"" + field
							+ "\" in Class \"" + javaBeanClazz.getName()
							+ "\".");
				}
    		}
    	}
    	return javaBean;
    }




 
 

 
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值