利用Java反射机制将Json格式字符串反射为 Bean List

前面提到过Strtus2在2.1.6以后就将Json格式整合到Strtus中了,可见到struts-json-plugin,在Struts的文档里面有下面一段例子:

Example

Setup Action

This simple action has some fields:

Example:

import java.util.HashMap; import java.util.Map; import com.opensymphony.xwork2.Action; public class JSONExample { private String field1 = "str"; private int[] ints = {10, 20}; private Map map = new HashMap(); private String customName = "custom"; //'transient' fields are not serialized private transient String field2; //fields without getter method are not serialized private String field3; public String execute() { map.put("John", "Galt"); return Action.SUCCESS; } public String getField1() { return field1; } public void setField1(String field1) { this.field1 = field1; } public int[] getInts() { return ints; } public void setInts(int[] ints) { this.ints = ints; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } @JSON(name="newName") public String getCustomName() { return this.customName; }

Write the mapping for the action

  1. Add the map inside a package that extends "json-default"
  2. Add a result of type "json"

Example:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="example" extends="json-default"> <action name="JSONExample" class="example.JSONExample"> <result type="json"/> </action> </package> </struts>
JSON example output
{ "field1" : "str", "ints": [10, 20], "map": { "John":"Galt" }, "newName": "custom" }
如例子中所示,根据配置Strtus会通过JsonUtil将对象转换为Json格式的字符串,然后通过流返回给客户端,但当Ext返回Json对象的时候,JsonUtil的反序列化功能似乎逊色了许多,大概看了一下源代码JsonUtil中能将Json格式的对象集合转为List<Map<Objcet,Object>>这种格式,而不能映射到实体类,现实中Json的工具还有许多,例如google的Json工具就提供了fromJson的方法,在这里我只是利用Java反射写了一个对简单类型反射的工具类,说了这么多废话,切入正题:

public static <T> List<T> fromJson(String json, Class<T> cls, SimpleDateFormat sdf) { List<T> result = new ArrayList<T>(); try { Map<String, Method> methodMap = new HashMap<String, Method>(); Method[] methods = cls.getMethods(); for (Method m : methods) { String name = m.getName().toUpperCase(); if (name.startsWith("SET") || name.startsWith("IS")) { methodMap.put(name.substring(3), m); } } List<Map<Object, Object>> list = (List<Map<Object, Object>>) JSONUtil .deserialize(json); for (Map<Object, Object> map : list) { Object o = cls.newInstance(); Iterator<Entry<Object, Object>> itr = map.entrySet().iterator(); while (itr.hasNext()) { Entry<Object, Object> entry = itr.next(); String key = entry.getKey().toString().toUpperCase(); if (methodMap.containsKey(key)) { Method _m = methodMap.get(key); Class<?> c = _m.getParameterTypes()[0]; if (c.getName().equals("int")) { _m.invoke(o, Integer.parseInt(entry.getValue() .toString())); } else if (c.getName().equals("long")) { _m.invoke(o, Long.parseLong(entry.getValue().toString())); } else if (c == Integer.class) { _m.invoke(o, (Integer) Integer.parseInt(entry .getValue().toString())); } else if (c == Long.class) { _m.invoke(o, (Long) Long.parseLong(entry.getValue() .toString())); } else if (c == String.class) { _m.invoke(o, entry.getValue().toString()); } else if (c == Date.class) { String date = entry.getValue().toString(); date = date.replaceFirst("T", " "); _m.invoke(o, sdf.parse(date)); } } } if (o != null) { System.out.println("sss"); result.add((T) o); } } } catch (JSONException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } return result; }
主要是找到SET方法然后将对应的属性设置进去,而对应的属性则是根据判断参数类型来进行的,再看下面这一句String date = entry.getValue().toString(); date = date.replaceFirst("T", " ");
Strtus2的Json Plugin似乎有一个问题目前还没有搞清楚,Strtus在将java.util.Date类型时间格式
2011-07-13 14:24:31
转换为Json字符串的时候变成了这个样子

2011-07-13T14:24:31
所以当提交回来的时候如果是这种时间格式是不能转换的,于是有了上面把T替换为“ ”的操作。

明天再研究一下到底是什么原因导致时间类型转换的异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值