fastjson:对象转化成json出现$ref

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"}]
    }

猜你喜欢

转载自blog.csdn.net/fly910905/article/details/81504388