为了账号安全,请及时绑定邮箱和手机立即绑定

杰克逊反序列化是否有最大的继承深度?

杰克逊反序列化是否有最大的继承深度?

撒科打诨 2023-02-16 17:21:49
换句话说,可以实现的继承深度是有限制的。目前我的深度为 2,祖父母 -> 父母 -> 孩子,我遇到了一个问题,杰克逊可以反序列化到父母,然后抛出一个 UnrecognizedPropertyException. 这是正确的,但是子类确实拥有该属性,我相信我已经为 Jackson 添加了正确的类型信息以反序列化子类。此测试显示问题:import com.fasterxml.jackson.annotation.JsonProperty;import com.fasterxml.jackson.annotation.JsonSubTypes;import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.annotation.JsonDeserialize;import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;import lombok.EqualsAndHashCode;import lombok.Getter;import lombok.Value;import lombok.experimental.SuperBuilder;import org.junit.Assert;import org.junit.Test;import java.io.IOException;import java.util.List;public class JacksonInheritanceTest {    @Test    public void deserializeChildrenAsGrandParentList() throws IOException {        ObjectMapper mapper = new ObjectMapper();        String grandparentsJson = "{" +                "\"list\":[{" +                "\"type\": \"parent\"," +                "\"value\": \"child\"," +                "\"someProperty\": \"foobar\"" +                "}]" +                "}";        GrandParentList grandparents = mapper.readValue(grandparentsJson, GrandParentList.class);        Assert.assertNotNull(grandparents);    }    @Test    public void deserializeParentAsGrandParent() throws IOException {        ObjectMapper mapper = new ObjectMapper();        String parentJson = "{" +                "\"type\": \"parent\"," +                "\"value\": \"child\"" +                "}";        GrandParent grandparent = mapper.readValue(parentJson, GrandParent.class);        Assert.assertNotNull(grandparent);    }
查看完整描述

2 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

以下是如何定义具有多个级别的继承:


您想要反序列化最终类型为“child”的 GrandParent 列表


  {

      "list":[{

          "type": "child",

          "someProperty": "foobar"

      }]

  }

继承树是:


GrandParent

  Parent

    Child(someProperty:String)

您必须在顶层定义您的“类型”属性,@JsonTypeInfo(...) 您可以在子级别上重复它,但如果您只序列化/反序列化祖父母则不需要。然后在每个父级(类 Parent 和 GrandParent)上定义子类型,就像您对 @JsonSubTypes 所做的那样。


代码


public class JacksonInheritanceTest2 {


    @Test

    public void deserializeChildrenAsGrandParentList() throws IOException {

        ObjectMapper mapper = new ObjectMapper();

        String grandparentsJson = "{" +

                "\"list\":[{" +

                "\"type\": \"child\"," +

                "\"someProperty\": \"foobar\"" +

                "}]" +

                "}";

        GrandParentList grandparents = mapper.readValue(grandparentsJson, GrandParentList.class);

        Assertions.assertNotNull(grandparents);

    }



}


class GrandParentList {

    @JsonProperty

    List<GrandParent> list;

}


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)

@JsonSubTypes({

        @JsonSubTypes.Type(value = Parent.class,name = "parent"),

        //@JsonSubTypes.Type(value = Child.class, name = "child")

})

class GrandParent {

    @JsonProperty("type")

    private String type;


}



//@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)

@JsonSubTypes({

        @JsonSubTypes.Type(value = Child.class, name = "child")

})

class Parent extends GrandParent {

    @JsonProperty

    private String value;


}


@JsonSubTypes({

    @JsonSubTypes.Type(value = Child.class, name = "child")

})

class Child extends Parent {

    @JsonProperty

    private String someProperty;


    public String getSomeProperty() {

        return someProperty;

    }


    public void setSomeProperty(String someProperty) {

        this.someProperty = someProperty;

    }




}

你做的错误:

  • 定义许多属性类型名称,每个属性类型名称用于一个父级:您选择您的属性类型名称并仅使用一个。

  • 在 Json 中,您确实在抽象中设置了父级的类型名称:只有叶类型很重要,树的其余部分被扣除。

侧节点:来自 junit5,它与来自 junit4 的Assertions功能相同Assert


查看完整回答
反对 回复 2023-02-16
?
慕慕森

TA贡献1856条经验 获得超17个赞

在 ObjectMapper 对象上设置配置:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


查看完整回答
反对 回复 2023-02-16
  • 2 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信