fastjson:物件轉化成json出現$ref

琦彥發表於2018-08-08

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

 

相關文章