处理对象重复引用导致在json序列化时出现$ref
简单说,重复引用就是一个集合/对象中的多个元素/属性同时引用同一对象。
举例说明
-
重复引用
-
List<Object> list = new ArrayList<>();
-
Object obj = new Object();
-
list.add(obj);
-
list.add(obj);
-
FastJson对重复/循环引用的处理
首先,fastjson作为一款序列化引擎,不可避免的会遇到循环引用的问题,为了避免StackOverflowError异常,fastjson会对引用进行检测。
如果检测到存在重复/循环引用的情况,fastjson默认会以“引用标识”代替同一对象,而非继续循环解析导致StackOverflowError。
以上文例说明,查看json化后的输出
-
重复引用 JSON.toJSONString(list)
-
[
-
{}, //obj的实体
-
{
-
"$ref": "$[0]" //对obj的重复引用的处理
-
}
-
]
避免重复引用序列化时显示$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) 编辑 收藏 举报