1、问题:
业务数据需要返回一个实体DTO两个字段引用的是另一个相同的DTO,数据也相同,使用FastJson中的toJSONString方法,返回数据中第二哥参数就会自动转换为$ref
解决:转换时使用SerializerFeature.DisableCircularReferenceDetect 关闭引用检查
例如:
String str = JSONObject.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetet);
2、问题原因:
如图:
需要返回此实体,转换为String,files 和 formInfo字段是通过业务数据for循环进行赋值的,
@Data
public class TestDTO {
private List<AdminDTO> files;
private List<AdminDTO> formInfo;
}
3、 错误示范:例如图中插入代码,此时返回的数据就会是
{\"files\":[{\"adminEmail\":\"fileUrl\",\"adminId\":\"name\"}],\"formInfo\":[{\"$ref\":\"$.files[0]\"}]}
formInfo中的数据自动变成了$ref,这个是因为一个集合中,给相同的对象循环赋值时,它会认为是一个对象,就出现$ref,FastJson提供了SerializerFeature.DisableCircularReferenceDetect这个序列化选项,用来关闭引用检测。关闭引用检测后,重复引用对象时就不会被$ref代替,但是在循环引用时也会导致StackOverflowError异常。
HashMap<String, String> map = new HashMap<>();
map.put("name","fileUrl");
ArrayList<AdminDTO> list = new ArrayList<>();
TestDTO testDTO = new TestDTO();
for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
AdminDTO adminDTO = new AdminDTO();
adminDTO.setAdminId(stringStringEntry.getKey());
adminDTO.setAdminEmail(stringStringEntry.getValue());
list.add(adminDTO);
}
testDTO.setFiles(list);
testDTO.setFormInfo(list);
String str = JSONObject.toJSONString(testDTO);
return WrapperResponse.success(str);
4、正确示范:
HashMap<String, String> map = new HashMap<>();
map.put("name","fileUrl");
ArrayList<AdminDTO> list = new ArrayList<>();
TestDTO testDTO = new TestDTO();
for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
AdminDTO adminDTO = new AdminDTO();
adminDTO.setAdminId(stringStringEntry.getKey());
adminDTO.setAdminEmail(stringStringEntry.getValue());
list.add(adminDTO);
}
testDTO.setFiles(list);
testDTO.setFormInfo(list);
String str = JSONObject.toJSONString(testDTO, SerializerFeature.DisableCircularReferenceDetect);
return WrapperResponse.success(str);