JSON序列化的引用问题

394 阅读1分钟

前言:

前几天在工作的时候遇到了一个Java实体类序列化出现了$符号的问题,当时也不知道是怎么回事,后来查阅了网上的资料后发现是序列化的引用问题。

小Demo:

实体类如下:

#省略gate和set方法
public class Student {
    private int id;
    private String name;
    private List<String> habits;
}

测试代码:

 List<Student> students = new ArrayList<>();
        Student studentA = new Student();
        studentA.setId(1);
        studentA.setName("A");
        List<String> habitsList = new ArrayList<>();
        habitsList.add("篮球");
        habitsList.add("羽毛球");
        habitsList.add("乒乓球");
        studentA.setHabits(habitsList);


        students.add(studentA);
        students.add(studentA);
        students.add(studentA);
        System.out.println(JSON.toJSONString(students));

代码运行结果:

[{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"$ref":"$[0]"},{"$ref":"$[0]"}]

why,当时我也是一脸闷逼吧,为什么会这样子,后来才发现引用的分类是可以分为如下两类

1: 重复引用

一个对象重复多次出现

2:循环应用

互相引用,即JSON序列化出现$的情况,处理不好可能会报StackOverflowError异常。

因此,如何关闭呢,这里与alibabaJSONObject为例,其他序列化类其实也是大同小异啦?

全局关闭,直接设置序列化方式

JSONObject.DEFAULT_GENERATE_FEATURE =  SerializerFeature.DisableCircularReferenceDetect.getMask();
System.out.println(JSON.toJSONString(students));

临时关闭,暂时变化序列化方式

JSON.toJSONString(students,SerializerFeature.DisableCircularReferenceDetect)

上述两种方式,都可以序列化为如下

[{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"}]