Json体验之——Json-lib使用浅谈(三)

这部分主要讲将json解析成java。


使用JSONSerializer

1     // Using the JSONSerializer
2         JSONArray json2 = (JSONArray) JSONSerializer.toJSON("[1,2,3]");
3         // 将json转换成list
4         List java2 = (List) JSONSerializer.toJava(json2);
5         System.out.println("——用JSONSerializer将json转换list——" + java2);

结果

1 ——用JSONSerializer将json转换list——[1, 2, 3]

将json转换为java,String,number,boolean,list类型可以直接解析,其他类型会解析成DynaBean,java与json对应类型在系列一中有介绍

 1      // Json-lib can transform JSONObjects to either a DynaBean or an specific bean class.
 2         // When using DynaBean all arrays are converted to Lists, when using an
 3         // specific bean class the transformation will use type conversion if necessary on array properties.
 4 
 5         // Convert to DynaBean:直接用toBean方法,String,number,boolean,list可以直接转换,其他类型都转换为DynaBean
 6         String json = "{name=\"json\",bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2],map:{1:1,2:2}}";
 7         JSONObject jsonObject = JSONObject.fromObject(json);
 8         Object bean = JSONObject.toBean(jsonObject);
 9 
10         String name = (String) jsonObject.get("name");
11         Object property = PropertyUtils.getProperty(bean, "name");
12         System.out.println(name.getClass() + "——" + name + "|"
13                 + property.getClass() + "——" + property);
14 
15         Object func = jsonObject.get("func");
16         Object funcProperty = PropertyUtils.getProperty(bean, "func");
17         System.out.println(func.getClass() + "——" + func + "|"
18                 + funcProperty.getClass() + "——" + funcProperty);
19         // List expected = JSONArray.toList(jsonObject.getJSONArray("array"));
20         Object array = jsonObject.get("array");
21         Object arrayProperty = PropertyUtils.getProperty(bean, "array");
22         System.out.println(array.getClass() + "——" + array + "|"
23                 + arrayProperty.getClass() + "——" + arrayProperty);
24         Map map = (Map) jsonObject.get("map");
25         Object mapProperty = PropertyUtils.getProperty(bean, "map");
26         System.out.println(map.getClass() + "——" + map + "|"
27                 + mapProperty.getClass() + "——" + mapProperty);

结果

1 class java.lang.String——json|class java.lang.String——json
2 class net.sf.json.JSONFunction——function(a){ return a; }|class net.sf.json.JSONFunction——function(a){ return a; }
3 class net.sf.json.JSONArray——[1,2]|class java.util.ArrayList——[1, 2]
4 class net.sf.json.JSONObject——{"1":1,"2":2}|class net.sf.ezmorph.bean.MorphDynaBean——net.sf.ezmorph.bean.MorphDynaBean@29557211[
5   {2=2, 1=1}

从结果上看,map类型直接使用tobean()方法对象是MorphDynaBean类型,无法直接解析出具体类型,这种情况后面有交代如何做。


 

解析自定义类,只需要在tobean()方法中加入你要转换的类的class对象

1         // Convert to Bean:json转换自定义bean
2         String json3 = "{id:\"1\",name:\"123\"}";
3         JSONObject jsonObject3 = JSONObject.fromObject(json3);
4         MyBean2 bean2 = (MyBean2) JSONObject.toBean(jsonObject3, MyBean2.class);
5         Object objectName = jsonObject3.get("name");
6         String name2 = bean2.getName();
7         System.out.println(objectName.getClass() + "——" + objectName + "|"
8                 + name2.getClass() + "——" + name2);

结果

1 class java.lang.String——123|class java.lang.String——123

两种特殊情况,对象中包含自定义类,需要手动转换自定义类

官网上的解释:

There are two special cases when converting to an specific bean, if the target bean has a Map property and it must contain other beans, JSONObject.toBean() will transform the nested beans into DynaBeans. If you need those nested beans transformed into an specific class, you can either postprocess the Map attribute or provide hints on JSONObject‘s attributes for conversion. JSONObject.toBean() may be passed a third argument, a Map, that will provide thos hints. Every key must be either the name of a property or a regular expression matching the object‘s properties, and the value must be a Class.

The second case is similar and it happens when the target bean has a Collection (List) as a property and it must contain other beans. In this case there is no way to provide hints for class conversion. The only possible solution is to postprocess the collection transforming each DynaBean into an specific bean.

两种特殊情况,一种是map里包含自定义类,另一种是list中包含自定义类,这两种情况需要手动转换自定义类型,不然会得到DynaBean类型。

我们建一个Mybean3模拟这种情况,一个list,一个map都包含自定义类型Mybean2,这个类在系列二中定义,具体翻看前一个章节。

 1 public class MyBean3 {
 2 
 3     private List<MyBean2> mybean2List = new ArrayList<MyBean2>();
 4 
 5     private Map<String, MyBean2> mybean2Map = new HashMap<String, MyBean2>();
 6 
 7     public List<MyBean2> getMybean2List() {
 8         return mybean2List;
 9     }
10     public void setMybean2List(List<MyBean2> mybean2List) {
11         this.mybean2List = mybean2List;
12     }
13     public Map<String, MyBean2> getMybean2Map() {
14         return mybean2Map;
15     }
16     public void setMybean2Map(Map<String, MyBean2> mybean2Map) {
17         this.mybean2Map = mybean2Map;
18     }
19 
20 }

那这种情况的解析方法

 1      String jsonMyBean3 = "{‘mybean2List‘:[{‘id‘:‘1‘,‘name‘:‘mybean3‘}],‘mybean2Map‘:{‘1‘:{‘id‘:‘2‘,‘name‘:‘mybean3‘}}}";
 2         Map classMap2 = new HashMap();
 3         classMap2.put("mybean2List", MyBean2.class);
 4         // classMap2.put("mybean2Map", Map.class);
 5         MyBean3 mybean3 = (MyBean3) JSONObject.toBean(
 6                 JSONObject.fromObject(jsonMyBean3), MyBean3.class, classMap2);
 7         System.out.println("-------------"
 8                 + mybean3.getMybean2List().getClass() + "|"
 9                 + mybean3.getMybean2Map().getClass() + "|");
10         // List<MyBean2> mybean2List = mybean3.getMybean2List();
11         Morpher dynaMorpher = new BeanMorpher(MyBean2.class,
12                 JSONUtils.getMorpherRegistry());
13         MorpherRegistry morpherRegistry = new MorpherRegistry();
14         morpherRegistry.registerMorpher(dynaMorpher);
15         List output = new ArrayList();
16         for (Iterator i = mybean3.getMybean2List().iterator(); i.hasNext();) {
17             Object morph = morpherRegistry.morph(MyBean2.class, i.next());
18             output.add(morph);
19         }
20         mybean3.setMybean2List(output);
21         // 打印结果
22         for (MyBean2 object : mybean3.getMybean2List()) {
23             System.out.println("特殊转换list——" + object.getName());
24         }
25         // Map
26         morpherRegistry.registerMorpher(dynaMorpher);
27         Map outputMap = new HashMap();
28         for (Map.Entry outMap : mybean3.getMybean2Map().entrySet()) {
29             Object value = outMap.getValue();
30             outputMap.put(outMap.getKey(),
31                     morpherRegistry.morph(MyBean2.class, value));
32         }
33         mybean3.setMybean2Map(outputMap);
34         // 输出部分结果
35         for (Map.Entry<String, MyBean2> bean2Map : mybean3.getMybean2Map()
36                 .entrySet()) {
37             System.out.println("特殊转换map——" + bean2Map.getKey() + ":"
38                     + bean2Map.getValue());
39         }
40     }

结果

1 特殊转换list——mybean3十二月 21, 2014 3:14:58 下午 net.sf.ezmorph.bean.BeanMorpher morph
2 信息: Property ‘com.r.json.jsonlib.MyBean2.class‘ has no write method. SKIPPED.
3 
4 十二月 21, 2014 3:14:58 下午 net.sf.ezmorph.bean.BeanMorpher morph
5 信息: Property ‘com.r.json.jsonlib.MyBean2.class‘ has no write method. SKIPPED.
6 特殊转换map——1:com.r.json.jsonlib.MyBean2@282c1e2e

list中包含自定义对象,可以将自定义类型放到一个map里,tobean()方法里多一个classMap参数,但经过测试这个参数没有也是可以的。

这包不方便的地方,这个里面的自定义类型需要自己手动转换,用例子中的方法。结果中打印里一些信息,“no write method”,经过看源码,是反射类属性时,类中的class对象没有write方法,不影响解析。


总结:从json解析java对象,一般的内容使用JSONObject或JSONArray的toBean方法即可,若是自定义类型,使用带class对象参数的toBean方法,,若是list,map中包含自定义类型,则在使用toBean方法后,要手动转换DynaBean类型到实际类型。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。