问题复现
依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
代码:
public class Test {
public static void main(String[] args) {
A a = new A("小亮");
A a2 = new A("小白");
A a3 = new A("小天");
List<A> list = new ArrayList<>();
list.add(a);
list.add(a2);
list.add(a3);
B b = new B(a, list);
System.out.println(JSONObject.toJSONString(b));
}
}
class A {
private String name;
public A(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class B {
private A entity;
private List<A> entityList;
public B(A entity, List<A> entityList) {
this.entity = entity;
this.entityList = entityList;
}
public A getEntity() {
return entity;
}
public void setEntity(A entity) {
this.entity = entity;
}
public List<A> getEntityList() {
return entityList;
}
public void setEntityList(List<A> entityList) {
this.entityList = entityList;
}
}
结果:
{"entity":{"name":"小亮"},"entityList":[{"$ref":"$.entity"},{"name":"小白"},{"name":"小天"}]}
分析:
里面出现了{"$ref":"$.entity"}
,原因是对象a不仅是对象b中的一个属性,它也是list集合中的一个元素,所以这就是问题所在;
出现该问题的原因:
fastjson作为一款序列化引擎,不可避免的会遇到循环引用的问题,为了避免StackOverflowError异常,fastjson会对引用进行检测。如果检测到存在重复/循环引用的情况,fastjson默认会以“引用标识”代替同一对象,而非继续循环解析导致StackOverflowError,fastjson使用这种方式来解决该问题,不过也导致了错误的出现。
解决办法
方法1(关闭检查):
在JSONObject.toJSONString()
方法中添加第2个参数’SerializerFeature.DisableCircularReferenceDetect",如下:
System.out.println(JSONObject.toJSONString(b, SerializerFeature.DisableCircularReferenceDetect));
方法2(创建新对象,解除循环引用):
创建新对象a1,替代b对象中的属性对象a,那么对象a只是list集合中的一个元素,这就解决问题了,即用:
A a1 = new A(a.getName());
B b = new B(a1, list);
替换:
B b = new B(a, list);