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
新增属性 clzes
序列化成功,反序列化失败
代码在生产 group2 提示
根据官网的示例:
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(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
3 楼
wenshao
2011-10-08
回复 littleJava,List<Class>反序列化的BUG已经修正。http://code.alibabatech.com/jira/browse/FASTJSON-104
4 楼
runfriends
2011-10-09
温少:
为什么下述用fastjson序列化的json串不能用firefox自带JSON解析器反序列化成js对象
fastjson序列化结果:[{"accessFlag":"1","desc":"用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n \r\nImport S-CONDITION NAME BIRTHDAY\r\n \r\nExport T-SEARCHRES T-RETURN","endClassname":"com.hiaward.xbankmibs.bpm.service.accountIgt.action.BPSearchEndAction","escnname":"用户定位\n\n ZBP_PER_SEARCH_CONDITION \n 个人信息搜索\n \n Import S-CONDITION NAME BIRTHDAY\n \n Export T-SEARCHRES T-RETURN","exceptionflag":0,"id":269,"isParent":true,"journalflag":0,"projectid":1,"remoteAccessType":"1","remoteAccessUrl":"","routerId":"0000000001","serviceHandlerType":"0","servicename":"ES-EX-SearchClientInfoHead-T","servicenum":"ES-EX-SearchClientInfoHead-T","startClassname":"com.hiaward.xbankmibs.bpm.service.accountIgt.action.SearchClientStartAction","type":1,"uptime":1316669923890,"version":""}]
jackson序列化结果
{
"id": 269,
"type": 1,
"domain": null,
"version": "",
"servicename": "ES-EX-SearchClientInfoHead-T",
"servicenum": "ES-EX-SearchClientInfoHead-T",
"escnname": "用户定位\n\n\t\t\tZBP_PER_SEARCH_CONDITION \n\t\t\t个人信息搜索\n\t\t\t\n\t\t\tImport S-CONDITION NAME BIRTHDAY\n\t\t\t\n\t\t\tExport T-SEARCHRES T-RETURN",
"projectid": 1,
"prodesc": null,
"developer": null,
"journalflag": 0,
"routerId": "0000000001",
"serviceCategory": null,
"desc": "用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n\t\t\t\r\nImport S-CONDITION NAME BIRTHDAY\r\n\t\t\t\r\nExport T-SEARCHRES T-RETURN",
"desc": "用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n \r\nImport S-CONDITION NAME BIRTHDAY\r\n \r\nExport T-SEARCHRES T-RETURN"
"accessFlag": "1",
"remoteAccessType": "1",
"remoteAccessUrl": "",
"serviceHandlerType": "0",
"asname": null,
"endClassname": "com.hiaward.xbankmibs.bpm.service.accountIgt.action.BPSearchEndAction",
"startClassname": "com.hiaward.xbankmibs.bpm.service.accountIgt.action.SearchClientStartAction",
"cpcflag": null,
"exceptionflag": 0,
"uptime": 1316669923890,
"usableflag": null,
"wipeoff": null,
"refedByProdesc": null,
"isParent": true,
"trTemplate": null
}
我在firefox使用 JSON.parse()解析上述json串时出错
错误内容是:SyntaxError: JSON.parse: bad control character in string literal
而我用jackson就不会出错。
两个库的惟一不同在于原java对象的属性值,连贯的\t在fastjson都被序列化成了一个空格,而jackson没有针对\t做这样的处理。
请温少指教。
为什么fastjson要针对\t做这样的处理?另外我实在找不到firefox JSON不能反序列化上述fastjson生成的json串的原因。
为什么下述用fastjson序列化的json串不能用firefox自带JSON解析器反序列化成js对象
fastjson序列化结果:[{"accessFlag":"1","desc":"用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n \r\nImport S-CONDITION NAME BIRTHDAY\r\n \r\nExport T-SEARCHRES T-RETURN","endClassname":"com.hiaward.xbankmibs.bpm.service.accountIgt.action.BPSearchEndAction","escnname":"用户定位\n\n ZBP_PER_SEARCH_CONDITION \n 个人信息搜索\n \n Import S-CONDITION NAME BIRTHDAY\n \n Export T-SEARCHRES T-RETURN","exceptionflag":0,"id":269,"isParent":true,"journalflag":0,"projectid":1,"remoteAccessType":"1","remoteAccessUrl":"","routerId":"0000000001","serviceHandlerType":"0","servicename":"ES-EX-SearchClientInfoHead-T","servicenum":"ES-EX-SearchClientInfoHead-T","startClassname":"com.hiaward.xbankmibs.bpm.service.accountIgt.action.SearchClientStartAction","type":1,"uptime":1316669923890,"version":""}]
jackson序列化结果
{
"id": 269,
"type": 1,
"domain": null,
"version": "",
"servicename": "ES-EX-SearchClientInfoHead-T",
"servicenum": "ES-EX-SearchClientInfoHead-T",
"escnname": "用户定位\n\n\t\t\tZBP_PER_SEARCH_CONDITION \n\t\t\t个人信息搜索\n\t\t\t\n\t\t\tImport S-CONDITION NAME BIRTHDAY\n\t\t\t\n\t\t\tExport T-SEARCHRES T-RETURN",
"projectid": 1,
"prodesc": null,
"developer": null,
"journalflag": 0,
"routerId": "0000000001",
"serviceCategory": null,
"desc": "用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n\t\t\t\r\nImport S-CONDITION NAME BIRTHDAY\r\n\t\t\t\r\nExport T-SEARCHRES T-RETURN",
"desc": "用户定位\r\n\r\nZBP_PER_SEARCH_CONDITION \r\n个人信息搜索\r\n \r\nImport S-CONDITION NAME BIRTHDAY\r\n \r\nExport T-SEARCHRES T-RETURN"
"accessFlag": "1",
"remoteAccessType": "1",
"remoteAccessUrl": "",
"serviceHandlerType": "0",
"asname": null,
"endClassname": "com.hiaward.xbankmibs.bpm.service.accountIgt.action.BPSearchEndAction",
"startClassname": "com.hiaward.xbankmibs.bpm.service.accountIgt.action.SearchClientStartAction",
"cpcflag": null,
"exceptionflag": 0,
"uptime": 1316669923890,
"usableflag": null,
"wipeoff": null,
"refedByProdesc": null,
"isParent": true,
"trTemplate": null
}
我在firefox使用 JSON.parse()解析上述json串时出错
错误内容是:SyntaxError: JSON.parse: bad control character in string literal
而我用jackson就不会出错。
两个库的惟一不同在于原java对象的属性值,连贯的\t在fastjson都被序列化成了一个空格,而jackson没有针对\t做这样的处理。
请温少指教。
为什么fastjson要针对\t做这样的处理?另外我实在找不到firefox JSON不能反序列化上述fastjson生成的json串的原因。
5 楼
aochant
2011-10-18
我想拍一砖,这两天拜读了sql parser,没注释,文档就几行测试代码,
只能看源码,源码写得很漂亮,鄙人实在不才 ,看得很吃力
这开源开得也太没诚意了,起码写写实现思路啥的吧 亲
只能看源码,源码写得很漂亮,鄙人实在不才 ,看得很吃力
这开源开得也太没诚意了,起码写写实现思路啥的吧 亲
6 楼
robinfoxnan
2011-10-30
TO runfriends :
我猜,那些\t之间可能是空值,或者什么的,
\t用来占位,
如果缺少了,就会错误,
仅仅猜测而已。
路过。
我猜,那些\t之间可能是空值,或者什么的,
\t用来占位,
如果缺少了,就会错误,
仅仅猜测而已。
路过。