[BUG]反序列化为JSONobject存在$ref引用,使用SerializerFeature.DisableCircularReferenceDetect会存在循环引用,栈溢出问题,生产环境不适用
问题描述
简要描述您碰到的问题。
环境信息
请填写以下信息:
- OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDK信息: [e.g.:Openjdk 1.8.0_312]
- 版本信息:[e.g.:Fastjson2 2.x.x]
重现步骤
如何操作可以重现该问题:
- 使用
xxx.xxx方法 - 输入
...数据 - 出现
...错误
//可在此输入示例代码
期待的正确结果
对您期望发生的结果进行清晰简洁的描述。
相关日志输出
请复制并粘贴任何相关的日志输出。
附加信息
如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。
能提供一下复现问题的测试用例吗?
能够提供一下恢复现有问题的测试示例吗?
@Test
public void testSetString() {
Person person = new Person("Alice");
Department department = new Department("Tech");
department.getMembers().add(person);
department.getMembers().add(person);
String jsonStringWithRef = JSON.toJSONString(department);
System.out.println("JSON with $ref:");
System.out.println(jsonStringWithRef);
JSONObject jsonObject = JSON.parseObject(jsonStringWithRef);
System.out.println("--------1");
System.out.println(jsonObject);
String jsonStringWithRef1 = JSON.toJSONString(department,SerializerFeature.DisableCircularReferenceDetect);
System.out.println("JSON with $ref1:");
System.out.println(jsonStringWithRef1);
JSONObject jsonObject1 = JSON.parseObject(jsonStringWithRef1);
System.out.println("--------2");
System.out.println(jsonObject1);
}
@Data
class Person {
private String name;
// getters and setters
public Person(String name) {
this.name = name;
}
}
@Data
class Department {
private String name;
private List<Person> members;
// getters and setters
public Department(String name) {
this.name = name;
this.members = new ArrayList<>();
}
}
JSON with $ref:
{"members":[{"name":"Alice"},{"$ref":"$.members[0]"}],"name":"Tech"}
--------1
{"members":[{"name":"Alice"},{"$ref":"$.members[0]"}],"name":"Tech"}
JSON with $ref1:
{"members":[{"name":"Alice"},{"name":"Alice"}],"name":"Tech"}
--------2
{"members":[{"name":"Alice"},{"name":"Alice"}],"name":"Tech"}
String jsonStringWithRef1 = JSON.toJSONString(department,SerializerFeature.DisableCircularReferenceDetect); 虽然解决了这个问题,但是会引发新的问题,循环引用,栈溢出。代码看下一贴
能够提供一下恢复现有问题的测试示例吗?
@Test
public void testSetString() {
Person person = new Person("Alice");
Department department = new Department("Tech");
person.setDepartment(department);
department.getMembers().add(person);
department.getMembers().add(person);
String jsonStringWithRef = JSON.toJSONString(department);
System.out.println("JSON with $ref:");
System.out.println(jsonStringWithRef);
JSONObject jsonObject = JSON.parseObject(jsonStringWithRef);
System.out.println("--------1");
System.out.println(jsonObject);
String jsonStringWithRef1 = JSON.toJSONString(department,SerializerFeature.DisableCircularReferenceDetect);
System.out.println("JSON with $ref1:");
System.out.println(jsonStringWithRef1);
JSONObject jsonObject1 = JSON.parseObject(jsonStringWithRef1);
System.out.println("--------2");
System.out.println(jsonObject1);
}
@Data
class Person {
private String name;
private Department department;
// getters and setters
public Person(String name) {
this.name = name;
}
}
@Data
class Department {
private String name;
private List<Person> members;
// getters and setters
public Department(String name) {
this.name = name;
this.members = new ArrayList<>();
}
}
JSON with $ref:
{"members":[{"department":{"$ref":"$"},"name":"Alice"},{"$ref":"$.members[0]"}],"name":"Tech"}
--------1
{"members":[{"name":"Alice","department":{"$ref":"$"}},{"$ref":"$.members[0]"}],"name":"Tech"}
java.lang.StackOverflowError
at com.alibaba.fastjson.serializer.JavaBeanSerializer.writeReference(JavaBeanSerializer.java:548)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:185)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:160)
at com.alibaba.fastjson.serializer.ListSerializer.write(ListSerializer.java:135)
at com.alibaba.fastjson.serializer.FieldSerializer.writeValue(FieldSerializer.java:324)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:454)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:160)
at com.alibaba.fastjson.serializer.FieldSerializer.writeValue(FieldSerializer.java:324)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:454)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:160)
您使用的是兼容包吗?SerializerFeature 是fastjson1.x的组件
您使用的是兼容包吗?SerializerFeature 是fastjson1.x的组件
提单的位置放错了。使用的fastjson1.x。
您使用的是兼容包吗?SerializerFeature 是fastjson1.x的组件
提单的位置放错了。使用的fastjson1.x。
1.x 现在已经停止维护了,可以尝试使用兼容包,或升级为2.x(或者尝试使用1.x的最后版本1.2.83)