- FastJson在序列化集合时,默认是开启了循环引用特性的,若集合中存在重复的元素,会使用元素索引的方式来存储后续的重复元素,以达到减小序列化输出体积的目的。
输出结果中会出现类似【{"$ref":"$[0]"}】的乱码,导致前端解析异常。 - 若反序列化用的也是FastJson,是能正常解析的,若不是则需要特殊处理:可以采用【集合去重、禁用FastJson循环依赖检查】等手段。
package com.yang;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.ArrayList;
import java.util.List;
/**
* @description: FastJson循环引用特性
* @author: Yang JianXiong
* @since: 2022/11/16
*/
public class Go {
public int id;
public String name;
public Go(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Go a = new Go(1, "a");
Go b = new Go(2, "b");
List<Go> list0 = new ArrayList<>();
list0.add(a);
list0.add(b);
System.out.println("1.不重复,序列化结果:" + JSON.toJSONString(list0));
List<Go> list = new ArrayList<>();
list.add(a);
list.add(a);
String json = JSON.toJSONString(list);
System.err.println("2.重复,序列化结果:" + json);
System.err.println("3.重复,但【禁止循环引用检查】,序列化结果:" + JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect));
List<Go> listFromDeserialize = JSON.parseObject(json, new TypeReference<List<Go>>() {
});
System.err.println("4.重复,序列化后,再反序列化结果:" + JSON.toJSONString(listFromDeserialize));
}
}
输出结果:
1.不重复,序列化结果:[{"id":1,"name":"a"},{"id":2,"name":"b"}]
2.重复,序列化结果:[{"id":1,"name":"a"},{"$ref":"$[0]"}]
3.重复,但【禁止循环引用检查】,序列化结果:[{"id":1,"name":"a"},{"id":1,"name":"a"}]
4.重复,序列化后,再反序列化结果:[{"id":1,"name":"a"},{"$ref":"$[0]"}]