日期:2014-05-16  浏览次数:20466 次

fastjson实现自省功能优化
JSON标准是不支持自省的,也就是说如下的JSON文本,你不知道它是什么类型:
{"id":12,"name":"魏嘉留"}


fastjson支持传入类型信息,例如:

String text = ...; // {"id":12,"name":"魏嘉留"}
JSON.parseObject(text, Employee.class);


如果序列化时,使用WriteClassName的特性,JSON文本是这样:
Employee x = ...;
String text = JSON.toJSONString(x, SerializerFeature.WriteClassName);

上面例子中的JSON文本是:
{“@type”:"com.alibaba.demo.Employee", "id":12,"name":"魏嘉留"}


带有@type属性的文本将会被自动识别类型,上面的文本可以这样处理:
Employee x = (Employee) JSON.parse(text);


这就是Fastjson支持的自省功能。

但是使用WriteClassName之后,json文本的大小增加了许多,这个怎么办呢?fastjson 1.1.6版本将会做优化处理,非必要,不输出类型信息。
class A {
B getB();
setB(B b);
}


类A拥有属性B,A和B都是对象,但是反序列化的时候,能够根据Property的类型信息得到B的类型,这时只需要输出A的类型,不需要输出B的类型信息。

例如:
{"@type":"com.alibaba.json.demo.A","b":{"id":0}}


在1.1.5之前的版本则会如下:
{"@type":"com.alibaba.json.demo.A","b":{"@type":"com.alibaba.json.demo.B","id":0}}


通过这种办法可以用List<T>类型的属性,由此能够减少冗余不必要的类型信息。

如下是一些测试用例:
http://code.alibabatech.com/svn/fastjson/trunk/fastjson/src/test/java/com/alibaba/json/test/bvt/writeClassName/WriteClassNameTest2.java

http://code.alibabatech.com/svn/fastjson/trunk/fastjson/src/test/java/com/alibaba/json/test/bvt/writeClassName/WriteClassNameTest_List2.java 
1 楼 wuku 2011-09-26  
温少,你太给力了!!!做开源做到你这个份上,真是太佩服了。如果淘宝里都是像你这么有责任心的人,淘宝想不发都难
2 楼 littleJava 2011-09-30  
fastjson 不支持 List<Class> 类型的数据吗?

根据官网的示例:
http://119.38.217.15/wiki/display/FastJSON/JavaBean+to+JSONString
public class Group {
    private Long id;
    private String name;
    private List<User> users = new ArrayList<User>();
    private List<Class> clzes = new ArrayList<Class>();
    /** setter && getter **/
}


新增属性 clzes
序列化成功,反序列化失败
    public void serialize() {
        Group group = new Group();
        group.setId(0L);
        group.setName("admin");
        User guestUser = new User();
        guestUser.setId(2L);
        guestUser.setName("guest");
        User rootUser = new User();
        rootUser.setId(3L);
        rootUser.setName("root");
        group.getUsers().add(guestUser);
        group.getUsers().add(rootUser);
        group.getClzes().add(Integer.class);
        group.getClzes().add(int.class);
        String jsonString = JSON.toJSONString(group);
        System.out.println(jsonString);
        Group group2 = JSON.parseObject(jsonString, Group.class); 
}

代码在生产 group2 提示
com.alibaba.fastjson.JSONException: not support type : null
	at com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer.deserialze(DefaultObjectDeserializer.java:246)
	at Fastjson_ASM_Group_1.deserialze(Unknown Source)
	at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:377)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:198)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:158)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:273)
	at org.netease.socketio.util.FastjsonTest.serialize(FastjsonTest.java:50)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAc