Fastjson:Maven依赖
<!-- FASTJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.20</version>
</dependency>
问题现象:$ref
package json;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
/**
* fastjson中$ref对象重复引用问题
*/
public class TestFastJson {
List<Person> list = new ArrayList<Person>();
Person p = new Person("FLY", 25);
/**
* 测试main
*/
public static void main(String[] args) {
new TestFastJson().test1();
}
/**
* 未关闭引用检测,转化字符串时会出现$ref
*/
public void test1() {
list.add(p);
list.add(p);
String jsonStr = JSON.toJSONString(list);
System.out.println(jsonStr);
// [{"age":25,"name":"FLY"},{"$ref":"$[0]"}]
}
}
class Person {
private String name;
private int age;
// 构造函数
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
问题分析:$ref
- 实体转化为json字符串后出现了$ref字样的东西,这是因为在传输的数据中出现相同的对象时,fastjson默认开启引用检测将相同的对象写成引用的形式
-
引用是通过"$ref"来表示的
引用 描述 "$ref":".." 上一级 "$ref":"@" 当前对象,也就是自引用 "$ref":"$" 根对象 "$ref":"$.children.0" 基于路径的引用,相当于 root.getChildren().get(0) - 说到引用分为两种,重复引用和循环引用
重复引用
- 指一个对象重复出现多次
循环引用
- 指你心里有我,我心里有你(互相引用),这个问题比较严重,如果处理不好就会出现StackOverflowError异常
问题解决:$ref
重复引用的解决方法;
1.单个关闭 JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
2.全局配置关闭 JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
循环引用的解决方法:
1.如果你前端用不到这个属性在该属性的get方法上加上注解@JSONField(serialize=false),
这样该属性就不会被序列化出来,这个也可以解决重复引用
2.修改表结构,出现循环引用了就是一个很失败的结构了,不然准备迎接StackOverflowError异常。
- 文章开头,示例中的问题,就可以这样解决
/**
* 关闭引用检测后,$ref的问题就会被解决
*/
public void test2() {
list.add(p);
list.add(p);
String jsonStr = JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect);
System.out.println(jsonStr);
// [{"age":25,"name":"FLY"},{"age":25,"name":"FLY"}]
}