使用FastJSON实现多态支持(又快又强)
FastJson 可谓是史上最快的JSON解析库!
但这不是本文的重点。
主要想说下基于FastJson的一种通用泛型解析的方案,也就是对于多态的支持。
又快又强
简单地说,就是我们使用FastJson,调用JSON.parseObject(jsonstr, XXX.class)方法的时候,如果XXX是一个抽象类,或者接口,这时候会得到的结果是null,也就说我们是没有办法只指定一个抽象类(或者接口),它就能直接根据json字符串中提供的实现类信息,帮我们解析成相应的实现类的。
那么如何实现它对多态的支持呢?
FastJson给我们提供了一种方式:
当我们将具体实现类解析为JSON字符串时,我们可以为其指定SerializerFeature。
通过添加SerializerFeature.WriteClassName,将在生成的json字符串中,添加序列化信息。
代码如下:
假设有个抽象类A:
abstract class A;
实现类B 和 C:
class B extends A;
class C extends A;
当我们将B或者C解析为JSON时,我们添加SerializerFeature:
B b = new B();
JSONObject.toJSONString(b, SerializerFeature.WriteClassName);
此时解析成功的JSON内容如下:
{
"@type":"com.json.test.dto.B",
"test":"1392"
}
将携带一个@type的属性,指定了序列化的类。
之后我们便可以直接使用抽象类A,通过反序列化解析字符串,得到具体的实现类了。
JSONObject.parseObject(str, A.class); // 根据@type,得到结果是 b
要注意的是,FastJSON在1.2.25之后的版本,增加了autotype功能的限制,该版本及该版本后的JSON解析,在进行多态转换的时候,会报出异常:
autotype is not support
该安全升级包禁用了部分autotype的功能,也就是"@type"这种指定类型的功能会被限制在一定范围内使用。
此时我们需要通过配置来开启autoType,FastJSON的官方wiki提供了解决方案。
建议使用以下解决方案:
通过类路径的fastjson.properties文件来配置,配置方式如下:
fastjson.parser.autoTypeAccept=com.taobao.pac.client.sdk.dataobject.,com.cainiao. // 如果有多个包名前缀,用逗号隔开
注意包路径结尾的 .