猿问

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

换句话说,可以实现的继承深度是有限制的。目前我的深度为 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);

    }

撒科打诨
浏览 137回答 2
2回答

蓝山帝景

以下是如何定义具有多个级别的继承:您想要反序列化最终类型为“child”的 GrandParent 列表&nbsp; {&nbsp; &nbsp; &nbsp; "list":[{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "type": "child",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "someProperty": "foobar"&nbsp; &nbsp; &nbsp; }]&nbsp; }继承树是:GrandParent&nbsp; Parent&nbsp; &nbsp; Child(someProperty:String)您必须在顶层定义您的“类型”属性,@JsonTypeInfo(...) 您可以在子级别上重复它,但如果您只序列化/反序列化祖父母则不需要。然后在每个父级(类 Parent 和 GrandParent)上定义子类型,就像您对 @JsonSubTypes 所做的那样。代码public class JacksonInheritanceTest2 {&nbsp; &nbsp; @Test&nbsp; &nbsp; public void deserializeChildrenAsGrandParentList() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper mapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; String grandparentsJson = "{" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\"list\":[{" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\"type\": \"child\"," +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\"someProperty\": \"foobar\"" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "}]" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "}";&nbsp; &nbsp; &nbsp; &nbsp; GrandParentList grandparents = mapper.readValue(grandparentsJson, GrandParentList.class);&nbsp; &nbsp; &nbsp; &nbsp; Assertions.assertNotNull(grandparents);&nbsp; &nbsp; }}class GrandParentList {&nbsp; &nbsp; @JsonProperty&nbsp; &nbsp; List<GrandParent> list;}@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)@JsonSubTypes({&nbsp; &nbsp; &nbsp; &nbsp; @JsonSubTypes.Type(value = Parent.class,name = "parent"),&nbsp; &nbsp; &nbsp; &nbsp; //@JsonSubTypes.Type(value = Child.class, name = "child")})class GrandParent {&nbsp; &nbsp; @JsonProperty("type")&nbsp; &nbsp; private String type;}//@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)@JsonSubTypes({&nbsp; &nbsp; &nbsp; &nbsp; @JsonSubTypes.Type(value = Child.class, name = "child")})class Parent extends GrandParent {&nbsp; &nbsp; @JsonProperty&nbsp; &nbsp; private String value;}@JsonSubTypes({&nbsp; &nbsp; @JsonSubTypes.Type(value = Child.class, name = "child")})class Child extends Parent {&nbsp; &nbsp; @JsonProperty&nbsp; &nbsp; private String someProperty;&nbsp; &nbsp; public String getSomeProperty() {&nbsp; &nbsp; &nbsp; &nbsp; return someProperty;&nbsp; &nbsp; }&nbsp; &nbsp; public void setSomeProperty(String someProperty) {&nbsp; &nbsp; &nbsp; &nbsp; this.someProperty = someProperty;&nbsp; &nbsp; }}你做的错误:定义许多属性类型名称,每个属性类型名称用于一个父级:您选择您的属性类型名称并仅使用一个。在 Json 中,您确实在抽象中设置了父级的类型名称:只有叶类型很重要,树的其余部分被扣除。侧节点:来自 junit5,它与来自 junit4 的Assertions功能相同Assert

慕慕森

在 ObjectMapper 对象上设置配置:mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
随时随地看视频慕课网APP

相关分类

Java
我要回答