AI智能
改变未来

fastjson字符串转JSON的$ref问题

先说结论:

fastjson在把对象转换成字符串的时候,如果遇到相同的对象的时候,默认开启引用检测将相同的对象写成引用的形式。

官网文档:https://github.com/alibaba/fastjson/wiki

问题出现的背景:

在开发过程中,使用了第三方的拓扑图组件。组件生成图形的json字符串在利用 fastjson 转换成 JSON 对象的时候报错如下所示:

Exception in thread \"main\" com.alibaba.fastjson.JSONException: illegal ref, int

后来定位到如下的字符串解析的时候会出错:

public class test {public static void main(String[] args) {String str1 = \"{\\\"$position\\\":{\\\"$ref\\\":21}}\";String str2 = \"{\\\"position\\\":{\\\"ref\\\":21}}\";JSONObject json = JSONObject.parseObject(str1);}}

解析str2没问题,解析str1报错

Exception in thread \"main\" com.alibaba.fastjson.JSONException: illegal ref, int

刚开始判断是$符号是特殊符号导致,所以去掉后解析str2没问题。

后来又测试下去掉第一个$

String str1 = \"{\\\"position\\\":{\\\"$ref\\\":21}}\";

还是报错:Exception in thread \”main\” com.alibaba.fastjson.JSONException: illegal ref, int

那么问题出现在第二个

$ref

上了。那么怀疑$ref 就好像保留字段一样,不能使用,于是修改为

String str1 = \"{\\\"position\\\":{\\\"$reff\\\":21}}\";

那么调用

JSONObject.parseObject(str1);

果然就正常了。

查阅官网资料:fastjson支持循环引用,并且是缺省打开的。

如果有相同的对象,那么 fastjson 会默认开启引用模式。

语法 描述
{\”$ref\”:\”$\”} 引用根对象
{\”$ref\”:\”@\”} 引用自己
{\”$ref\”:\”..\”} 引用父对象
{\”$ref\”:\”../..\”} 引用父对象的父对象
{\”$ref\”:\”$.members[0].reportTo\”} 基于路径的引用

官网还给出了说明:

当序列化后的JSON传输到浏览器或者其他语言中,这些json解析器不支持循环引用,从而导致数据丢失。你可以关闭fastjson的循环引用支持。关闭引用检测,还能够提升序列化时的性能。

全局配置关闭

JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();

非全局关闭

JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);

综上,我们的字符串中包括\”$ref\”,fastjson 认为这是引用模式,但是引用的值又是不正确的,导致出错。

解决方式上面说了两种,一种全局,一种非全局的。

我们采用非全局的,那么下面的代码就是正确✅的了

public class test {public static void main(String[] args) {String str1 = \"{\\\"$position\\\":{\\\"$reff\\\":21}}\";JSONObject json = JSONObject.parseObject(str1, Feature.DisableCircularReferenceDetect);System.out.println(json);}}结果:{\"$position\":{\"$reff\":21}}
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » fastjson字符串转JSON的$ref问题