码迷,mamicode.com
首页 > Web开发 > 详细

json-lib关键字class作为key产生的bug

时间:2015-07-21 01:15:43      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

   昨天用java写一个xml序列化成json的递归算法的时候遇到一个问题,遇到一个问题,就是用class做xml的元素或者属性的节点序列化不成功。后来,单步调试的时候,发现数据其实是从xml中读出来了的,并且存入了json对象中,但是在返回的时候没有返回成功。下面是xml序列化成json的方法:

技术分享
 1 /**
 2      * 迭代某元素,属性,文本,及下级元素,并将其转换为json对象
 3      */
 4    public  static JSONObject xmlToJson(Element e){
 5             JSONObject json=new JSONObject();
 6             //查看是否有文本数据
 7             String text=e.getTextTrim();
 8             if (text.length()!=0) {
 9                 json.put(R.S.TEXT,text);
10             }
11             //查看元素是否有属性
12             List<Attribute> attrs=e.attributes();
13             for (Attribute attr : attrs) {
14                 json.put(attr.getName(),attr.getValue());
15             }
16             //查看元素是否包含元素
17             List<Element> es=e.elements();
18             for (Element ele : es) {
19                  List<Element> elecount=e.elements(ele.getQName());
20                //说明该元素是唯一的,不做数组处理
21                  if (elecount.size()==1) {
22                         json.put(ele.getName(),xmlToJson(ele));
23                  }
24                  //说明该元素不是唯一的,应该以数组处理
25                  if (elecount.size()>1) {
26                      //之前已经遍历过了,此次不需要再遍历
27                      if (elecount.indexOf(ele)>0) {
28                             continue;
29                         }
30                     JSONArray arr=new JSONArray();
31                     String key=null;
32                     for (Element el: elecount) {
33                         if (key==null) {
34                             key=el.getName();
35                         }
36                         arr.add(xmlToJson(el));
37                     }
38                     json.put(key,arr);
39                 }
40             }
41             return json;
42    }
java code

下面是被测试的xml代码:

技术分享
 1     <!-- 实体类/entity/bean/pojo配置 -->
 2     <ll:entitys>
 3        <ll:pakage pakage="author.liulang.mybatis.entity"/>
 4        <ll:save path="author/liulang/mybatis/entity/"/>
 5        <ll:attr equal="public" getter="public" filed="private" hash="public" public="public" serial="true" setter="public" static="false" tostring="public"/>
 6        <ll:parent class="author.liulang.common.entity.BasicEntity"/>
 7        <ll:types>
 8          <ll:type db="int" java="int"/>
 9          <ll:type db="intunsigned" java="int"/>
10          <ll:type db="integer" java="int"/>
11          <ll:type db="char" java="String"/>
12          <ll:type db="tinyint" java="int"/>
13          <ll:type db="bigint" java="long"/>
14          <ll:type db="date" java="java.util.Date"/>
15          <ll:type db="datetime" java="java.util.Date"/>
16          <ll:type db="varchar" java="String"/>
17          <ll:type db="double" java="double"/>
18          <ll:type db="decimal" java="java.math.BigDecimal"/>
19          <ll:type db="float" java="float"/>
20          <ll:type db="text" java="String"/>
21          <ll:type db="int" java="int"/>
22        </ll:types>
23     </ll:entitys>
xml code

下面是调用测试代码:

技术分享
1    public static void main(String[] args) {
2         XmlUtils.setPath(C.F.X.LiuLang);
3      Element root= XmlUtils.open();
4      Element entitys = root.element("entitys");
5      JSONObject json= XmlUtils.xmlToJson(entitys);
6      System.err.println(json);
7      
8   }
caller Code

下面是调用后返回json代码的结果:

技术分享
 1 {
 2     "pakage": {
 3         "pakage": "author.liulang.mybatis.entity"
 4     },
 5     "save": {
 6         "path": "author/liulang/mybatis/entity/"
 7     },
 8     "attr": {
 9         "equal": "public",
10         "getter": "public",
11         "filed": "private",
12         "hash": "public",
13         "public": "public",
14         "serial": "true",
15         "setter": "public",
16         "static": "false",
17         "tostring": "public"
18     },
19     "parent": {},
20     "types": {
21         "type": [
22             {
23                 "db": "int",
24                 "java": "int"
25             },
26             {
27                 "db": "intunsigned",
28                 "java": "int"
29             },
30             {
31                 "db": "integer",
32                 "java": "int"
33             },
34             {
35                 "db": "char",
36                 "java": "String"
37             },
38             {
39                 "db": "tinyint",
40                 "java": "int"
41             },
42             {
43                 "db": "bigint",
44                 "java": "long"
45             },
46             {
47                 "db": "date",
48                 "java": "java.util.Date"
49             },
50             {
51                 "db": "datetime",
52                 "java": "java.util.Date"
53             },
54             {
55                 "db": "varchar",
56                 "java": "String"
57             },
58             {
59                 "db": "double",
60                 "java": "double"
61             },
62             {
63                 "db": "decimal",
64                 "java": "java.math.BigDecimal"
65             },
66             {
67                 "db": "float",
68                 "java": "float"
69             },
70             {
71                 "db": "text",
72                 "java": "String"
73             },
74             {
75                 "db": "int",
76                 "java": "int"
77             }
78         ]
79     }
80 }
json Code

通过结果看到,json对象的parent字段为空,而实际该字段的结果应该为{"class":"author.liulang.common.entity.BasicEntity"},不信我们把xml文件的parent元素class属性缓存cls,那么我们可以看到返回的结果中parent字段为:{"cls":"author.liulang.common.entity.BasicEntity"}:

下面是改后的xml代码:

技术分享
 1 <!-- 实体类/entity/bean/pojo配置 -->
 2     <ll:entitys>
 3        <ll:pakage pakage="author.liulang.mybatis.entity"/>
 4        <ll:save path="author/liulang/mybatis/entity/"/>
 5        <ll:attr equal="public" getter="public" filed="private" hash="public" public="public" serial="true" setter="public" static="false" tostring="public"/>
 6        <ll:parent cls="author.liulang.common.entity.BasicEntity"/>
 7        <ll:types>
 8          <ll:type db="int" java="int"/>
 9          <ll:type db="intunsigned" java="int"/>
10          <ll:type db="integer" java="int"/>
11          <ll:type db="char" java="String"/>
12          <ll:type db="tinyint" java="int"/>
13          <ll:type db="bigint" java="long"/>
14          <ll:type db="date" java="java.util.Date"/>
15          <ll:type db="datetime" java="java.util.Date"/>
16          <ll:type db="varchar" java="String"/>
17          <ll:type db="double" java="double"/>
18          <ll:type db="decimal" java="java.math.BigDecimal"/>
19          <ll:type db="float" java="float"/>
20          <ll:type db="text" java="String"/>
21          <ll:type db="int" java="int"/>
22        </ll:types>
23     </ll:entitys>
xml Code

下面是改后返回的json对象:

技术分享
 1 {
 2     "pakage": {
 3         "pakage": "author.liulang.mybatis.entity"
 4     },
 5     "save": {
 6         "path": "author/liulang/mybatis/entity/"
 7     },
 8     "attr": {
 9         "equal": "public",
10         "getter": "public",
11         "filed": "private",
12         "hash": "public",
13         "public": "public",
14         "serial": "true",
15         "setter": "public",
16         "static": "false",
17         "tostring": "public"
18     },
19     "parent": {
20         "cls": "author.liulang.common.entity.BasicEntity"
21     },
22     "types": {
23         "type": [
24             {
25                 "db": "int",
26                 "java": "int"
27             },
28             {
29                 "db": "intunsigned",
30                 "java": "int"
31             },
32             {
33                 "db": "integer",
34                 "java": "int"
35             },
36             {
37                 "db": "char",
38                 "java": "String"
39             },
40             {
41                 "db": "tinyint",
42                 "java": "int"
43             },
44             {
45                 "db": "bigint",
46                 "java": "long"
47             },
48             {
49                 "db": "date",
50                 "java": "java.util.Date"
51             },
52             {
53                 "db": "datetime",
54                 "java": "java.util.Date"
55             },
56             {
57                 "db": "varchar",
58                 "java": "String"
59             },
60             {
61                 "db": "double",
62                 "java": "double"
63             },
64             {
65                 "db": "decimal",
66                 "java": "java.math.BigDecimal"
67             },
68             {
69                 "db": "float",
70                 "java": "float"
71             },
72             {
73                 "db": "text",
74                 "java": "String"
75             },
76             {
77                 "db": "int",
78                 "java": "int"
79             }
80         ]
81     }
82 }
json Code

可以看到这时候json对象的parent字段不再为空,而是{"cls":"author.liulang.common.entity.BasicEntity"},那么我们可以初步得出结论,json对象不能解析key为class的数据,到底是不是这样呢?上面的代码因为涉及到递归,和一些其他相关联的步骤,并不能很好的说明这是json-lib的bug,好的下面我们来做一个进一步验证:

这里我在main方法中写了一段代码如下:

1    public static void main(String[] args) {
2        JSONObject json=new JSONObject();
3        json.put("class","我用class做了json对象的key");
4        System.err.println(json);
5        JSONObject json2=new JSONObject();
6        json2.put("class",json);
7        System.err.println(json2); 
8   }

下面做四个选项,你们猜猜答案是什么:

A.{"class":"我用class做了json对象的key"}

{"class":{"class":"我用class做了json对象的key"}}

B.{"class":}
{"class":{}}

C.{"class":"我用class做了json对象的key"}
{"class":{}}

D.{"class":}
{"class":{"class":"我用class做了json对象的key"}}

     如果按照正常情况,答案是A,可是用了关键字class作为key,答案确奇迹般的变成了C,这可以说是json-lib的一个bug了吧,我测试了其它部分关键字,尚未发现该现象。至于造成这种结果的原因还不明确,估计是因为json-lib中用过反射的缘故。

     通过这个问题也给我们提个醒:在编程中,定义字符串,变量名,属性名,元素名,方法名的时候虽然要做到见名知意,但是也应该尽量避免与系统中保留关键字,或者是重要关键字重名,遇到这种情况最好是采用该词的简写或者同义词代替,不然在编程中可能给我们带来不必要的麻烦,与此类似的问题,还比如JavaScript中,如果你定义的一个方法名恰好为accept,而且单独定义在一个js文件中,你会发现在调用该方法的时候,浏览器会报错,说这不是一个方法。accept我查过不是JavaScript关键字,其中的原因多半应该是与系统全局方法名或者属性名重复了,或者是与header头有冲突。

json-lib关键字class作为key产生的bug

标签:

原文地址:http://www.cnblogs.com/liulangdege/p/4663164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!