当前位置: 首页 > 知识库问答 >
问题:

多级@JSONTypeInfo和@JSONSubtypes

弓华茂
2023-03-14
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = B.class, name = "B")})
public abstract class A {

    private final String type;

    public A(String type) {
        this.type = type;
    }
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type2")
@JsonSubTypes({@JsonSubTypes.Type(value = C.class, name = "C")})
public class B extends A {

    private final String type2;

    private final String propertyB;

    @JsonCreator
    public B(@JsonProperty("type2") String type2,
             @JsonProperty("propertyB") String propertyB) {
        super("B");
        this.type2 = type2;
        this.propertyB = propertyB;
    }
}

public class C extends B {

    private final String propertyC;

    @JsonCreator
    public C(@JsonProperty("propertyB") String propertyB,
             @JsonProperty("propertyC") String propertyC) {
        super("C", propertyB);
        this.propertyC = propertyC;
    }
}
@Test
void whenReadCJsonToA_thenObjectIsInstanceOfC() throws JsonProcessingException {

    String json = "{\n" +
                  "  \"type\" : \"B\",\n" +
                  "  \"type2\" : \"C\",\n" +
                  "  \"propertyB\" : \"b\",\n" +
                  "  \"propertyC\" : \"c\"\n" +
                  "}";

    A obj = objectMapper.readValue(json, A.class);
    assertTrue(obj instanceof B, "obj is not instance of B");  // pass
    assertTrue(obj instanceof C, "obj is not instance of C");  // fail
}

我的maven项目可以在GitHub中找到。

共有1个答案

卫博学
2023-03-14

根据Jackson的这个问题,只支持一个类型discliminator属性的多级继承。在我的代码中,只保留属性type并删除属性type2

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = B.class, name = "B")})
public abstract class A {

    private final String type;

    public A(String type) {
        this.type = type;
    }
}

@JsonSubTypes({@JsonSubTypes.Type(value = C.class, name = "C")})
public class B extends A {

    private final String propertyB;

    @JsonCreator
    public B(@JsonProperty("propertyB") String propertyB) {
        super("B");
        this.propertyB = propertyB;
    }
}

public class C extends B {

    private final String propertyC;

    @JsonCreator
    public C(@JsonProperty("propertyB") String propertyB,
             @JsonProperty("propertyC") String propertyC) {
        super(propertyB);
        this.propertyC = propertyC;
    }
}

请参阅此提交中的完整代码。

此提交使用枚举作为类型discliminator属性类型。

 类似资料:
  • Jackson中使用的注释是什么? ======================================== ============================================== 我的理解是,它还保留了被序列化的对象的具体类型以及实际数据。 我不清楚的是反序列化过程中的实际优势/收益是什么。 除了java文档之外,没有任何重要的文档。任何人都可以在这里提供帮助或提供

  • 问题内容: 在jackson中使用的@JsonTypeInfo和@JsonSubTypes注释是什么? ======================================= ============================================== 我了解的是 ,它还保留了要序列化的对象的具体类型以及实际数据。 我不清楚 反序列化期间的实际优势/收益是什么。 除了Jav

  • 下面是一个多态字段: 其中是接口,是结构/类中其他位置的字段。 在这种情况下我怎么会有这种行为呢?

  • 问题内容: 我的Spring MVC(v3.2.0.RELEASE)Web应用程序中具有以下对象模型: 将Order类序列化为JSON时,得到以下结果(正是我想要的结果): 不幸的是,如果我使用上述JSON并尝试将其反序列化回我的对象​​模型,则会收到以下异常: 无法读取JSON:无法在[来源:org.apache.catalina.connector.CoyoteInputStream@1962

  • 问题内容: 因此,我了解到在Mockito中,@ InjectMocks将使用@Mock的注解注入所有可以注入的内容,但是如何处理这种情况呢? 假设MockObject2的属性类型为MockObject1,而SystemUnderTest的属性类型为MockObject2。我想将模拟对象1注入到模拟对象2中,并将模拟对象2注入到systemUnderTest中。 注释可以吗? 问题答案: 由于我在

  • 我知道删除或修改注释可以做到这一点,但在这种情况下这不是一个选项。 -将关闭所有注释。这确实删除了冒犯字段,但也扼杀了我想工作的其他注释。