处理对象重复引用导致在json序列化时出现$ref

简单说,重复引用就是一个集合/对象中的多个元素/属性同时引用同一对象。

举例说明

  1. 重复引用

    1. List<Object> list = new ArrayList<>();

    2. Object obj = new Object();

    3. list.add(obj);

    4. list.add(obj);

FastJson对重复/循环引用的处理

首先,fastjson作为一款序列化引擎,不可避免的会遇到循环引用的问题,为了避免StackOverflowError异常,fastjson会对引用进行检测。

如果检测到存在重复/循环引用的情况,fastjson默认会以“引用标识”代替同一对象,而非继续循环解析导致StackOverflowError。

以上文例说明,查看json化后的输出

  1. 重复引用 JSON.toJSONString(list)

  1. [

  2. {}, //obj的实体

  3. {

  4. "$ref": "$[0]" //对obj的重复引用的处理

  5. }

  6. ]

避免重复引用序列化时显示$ref

  在编码时,使用新对象为集合或对象赋值,而非使用同一对象
  不要在多处引用同一个对象,这可以说是一种java编码规范,需要时刻注意。

  如上例可改为:

List<Object> list = new ArrayList<>();
Object obj = new Object();
list.add(obj);
// 创建新的对象
Object newObj = new Object();
// 使用org.springframework.beans.BeansUtils复制属性值
BeansUtils.copy(obj, newObj);
list.add(newObj);

   注意:如果Object里有非基本类型则需要单独重新set否则也会出现$ref,比如下例的User,不同的User里如果posts如果有同一条post也会出现$ref,不可简单copy需要重新setPosts

 1 @Data
 2 public class User implements Serializable {
 3 
 4     private String nickname;
 5 
 6     private Integer age;
 7 
 8     private List<String> titles;
 9 
10     private List<Post> posts;
11 }

 

posted on 2021-05-12 14:47  Iversonstear  阅读(645)  评论(0编辑  收藏  举报

导航