fastjson 开启"$ref"循环引用时,部分场景反序列化出现空值Null

zaqlnxep  于 2021-11-27  发布在  Java
关注(0)|答案(7)|浏览(353)

开启"$ref"循环引用时,遇到反序列化后引用字段空值的问题。以下是实际工作中改写的例子demo:

public  class ApiResult<T> implements Serializable {
    private String msg;
    private int code;
    private T data;

    public ApiResult() {
    }

    public ApiResult(int code, String msg,T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public String getMsg() {
        return msg;
    }
    public int getCode() {
        return code;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public static <T> ApiResult<T> valueOfSuccess(T data) {
        return new ApiResult<T>(0, "Success", data);
    }

}

public class ClassForData implements Serializable {

    private String dataName;

    private FirstSubClass first;

    private SecondSubClass second;

    public String getDataName() {
        return dataName;
    }

    public void setDataName(String dataName) {
        this.dataName = dataName;
    }

    public FirstSubClass getFirst() {
        return first;
    }

    public void setFirst(FirstSubClass first) {
        this.first = first;
    }

    public SecondSubClass getSecond() {
        return second;
    }

    public void setSecond(SecondSubClass second) {
        this.second = second;
    }
}

public class FirstSubClass  implements Serializable{

    private String addr;//仅仅做下和second的区分

    private  SubCommonClass commonInfo;

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public SubCommonClass getCommonInfo() {
        return commonInfo;
    }

    public void setCommonInfo(SubCommonClass commonInfo) {
        this.commonInfo = commonInfo;
    }

}

public class SecondSubClass implements Serializable{

    private String name;

    private  SubCommonClass commonInfo;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SubCommonClass getCommonInfo() {
        return commonInfo;
    }

    public void setCommonInfo(SubCommonClass commonInfo) {
        this.commonInfo = commonInfo;
    }
}

public class SubCommonClass  implements Serializable{

    private Date demoDate;

    public SubCommonClass(){
    }

    public SubCommonClass(Date demoDate){
        this.demoDate = demoDate;
    }

    public Date getDemoDate() {
        return demoDate;
    }

    public void setDemoDate(Date demoDate) {
        this.demoDate = demoDate;
    }
}

public class TestMain{
     public static void main(String[] args) {
        ClassForData classForData = new ClassForData();
        classForData.setDataName("dataname");
        SubCommonClass commonClass = new SubCommonClass(new Date());

        FirstSubClass firstSubClass = new FirstSubClass();
        firstSubClass.setAddr("It is addr");
        firstSubClass.setCommonInfo(commonClass);

        SecondSubClass secondSubClass = new SecondSubClass();
        secondSubClass.setName("It is name");
        secondSubClass.setCommonInfo(firstSubClass.getCommonInfo());

        classForData.setFirst(firstSubClass);
        classForData.setSecond(secondSubClass);

        ApiResult<ClassForData> apiResult = ApiResult.valueOfSuccess(classForData);
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

        String jsonString = JSON.toJSONString(apiResult,SerializerFeature.WriteClassName);//这里加上SerializerFeature.DisableCircularReferenceDetect
        System.out.println(jsonString);
        Object obj = JSON.parse(jsonString);//这里加上Feature.DisableCircularReferenceDetect  这样的话 是可以避免空值的  ,但是$ref 还有啥意思呢
        System.out.println(JSON.toJSONString(obj));
     }
}

以上测试对应的输出

经过fastjson 序列化之后的:
{ "@type": "com.qunar.hotel.qta.order_port.base.util.demo.ApiResult", "code": 0, "data": { "@type": "com.qunar.hotel.qta.order_port.base.util.demo.ClassForData", "dataName": "dataname", "first": { "addr": "It is addr", "commonInfo": { "demoDate": 1509506892464 } }, "second": { "commonInfo": { "$ref": "$.data.first.commonInfo" }, "name": "It is name" } }, "msg": "Success" }
经过fastjson 反序列化的
{ "code": 0, "data": { "dataName": "dataname", "first": { "addr": "It is addr", "commonInfo": { "demoDate": 1509506892464 } }, "second": { "name": "It is name" } }, "msg": "Success" }
debug可以看到 second的commonInfo 是null,序列化为json串 因为是null值丢掉了

是不是很伤不起。

kx1ctssn

kx1ctssn1#

求指教 这个问题如何解

kjthegm6

kjthegm62#

自己顶起来 无人问津啊

yizd12fk

yizd12fk4#

新增加了testcae,但问题没从重现啊,什么版本呢?

hfwmuf9z

hfwmuf9z7#

用测试代码 1.2.30 我本地跑还是会有问题 1.2.39 解决了 是OK的

相关问题