fastjson循环依赖

举个例子

HashMap map = new HashMap();
map.put("foo", map);
System.out.println(map);

输出是:{foo=(this Map)},this Map代表map自己引用自己。
如果用fastjson序列换成json会怎么样呢?
fastjson处理json序列化的方法都放在JSON类中,主要有3个方法:

  • toJSON()
  • toJSONString()
  • toJSONByteds()

toJSON()

HashMap map = new HashMap();
map.put("foo", map);
System.out.println(JSON.toJSON(map));

汇报异常Exception in thread "main" java.lang.StackOverflowError,原因跟toJSON实现方式有关

JSONObject json = new JSONObject(innerMap);

for (Map.Entry<Object, Object> entry : map.entrySet()) {
    Object key = entry.getKey();
    String jsonKey = TypeUtils.castToString(key);
    Object jsonValue = toJSON(entry.getValue());//<--这里
    json.put(jsonKey, jsonValue);
}

可以看到对Map的value还会调用toJSON方法,造成了死循环,且对value处理前任何配置都没生效,所以toJSON方法对循环引用无解。

尝试一下toJSONString和toJSONBytes方法

HashMap map = new HashMap();
map.put("foo", map);
System.out.println(JSON.toJSONString(map));
System.out.println(new String(JSON.toJSONBytes(map)));

输出:{"foo":{"$ref":"@"}},跟直接print输出一致。这两个方法会依据配置SerializerFeature.DisableCircularReferenceDetect来控制是否开启重复引用检查,在处理value时判断上下文中是否已经存在对象。如果开启配置,且上下文中value对象已存在则用引用形式表示。

//JavaBeanSerializer.class
public boolean writeReference(JSONSerializer serializer, Object object, int fieldFeatures) {
    SerialContext context = serializer.context;
    int mask = SerializerFeature.DisableCircularReferenceDetect.mask;
    if (context == null || (context.features & mask) != 0 || (fieldFeatures & mask) != 0) {//<--这里
        return false;
    }

    if (serializer.references != null && serializer.references.containsKey(object)) {
        serializer.writeReference(object);
        return true;
    } else {
        return false;
    }
}

不同层级的引用会以不同的符号代替,具体可以参考JSONSerializer.writeReference()方法

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,790评论 19 139
  • 1.概述2.Gson的目标3.Gson的性能和扩展性4.Gson的使用者5.如何使用Gson 通过Maven来使用...
    人失格阅读 14,563评论 2 18
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 34,960评论 18 399
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 23,006评论 1 92
  • “老去”或许有点孤单,有点寂寞,有点无奈。 看着那几位手扶着走廊的栏杆,眼睛茫然地望着远方的老人,我不知道他们是在...
    静静如水阅读 331评论 0 1

友情链接更多精彩内容