您的位置:首页 > 编程语言 > Java开发

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

2011-07-14 00:13 525 查看
前面提到过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

Add the map inside a package that extends "json-default"
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替换为“ ”的操作。

明天再研究一下到底是什么原因导致时间类型转换的异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: