簡體   English   中英

傑克遜JAXB批注-根元素處的繼承映射

[英]jackson JAXB annotations - inheritance mapping at the root element

我有以下Jaxb注釋的類層次結構,包括在文檔根元素處的繼承:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParentClass", propOrder = {
        "parentField"
})
public class ParentClass{
    @XmlElement(name = "ParentField")
    protected String parentField;

  getters and setters here
}

ChildAClass:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ChildAClass", propOrder = {
        "childAfield"
})
public class ChildAClass extends ParentClass{

    @XmlElement(name = "ChildAfield")
    protected String childAfield;

  getters and setters here
}

ChildBClass:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ChildBClass", propOrder = {
        "childBfield"
})
public class ChildBClass extends ParentClass{

    @XmlElement(name = "ChildBfield")
    protected String childBfield;

  getters and setters here
}

那是非常簡單的類層次結構。 比起我進行序列化ChildAClass並嘗試反序列化為ParentClass的簡單測試而言。 我希望將propper類反序列化並向上轉換為ParentClass。 我想這是一個有效的用例。

序列化的文檔如下所示,這里沒有花哨的地方。

{
  "ChildAfield": "child A field",
  "ParentField": "parent from child A"
}

但是當我嘗試反序列化時:

    mapper = new ObjectMapper();
    JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
    mapper.registerModule(jaxbAnnotationModule);

    mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
    mapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, false);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_
ParentClass parentClass = mapper.readValue(new File(PATH_TO_FILE), ParentClass.class);

我收到以下異常:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ChildAfield" (class inheritance.model.ParentClass), not marked as ignorable (one known property: "ParentField"])
 at [Source: src/test/resources/testfiles/json/inheritance.json; line: 2, column: 19] (through reference chain: inheritance.model.ParentClass["ChildAfield"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty( ...

我想這里缺少一些類型元數據用於適當的類型推斷和反序列化。 我一直在尋找@JsonTypeInfo,但僅限於JAXB。 我嘗試了@XmlElements jaxb批注,但無法使其工作。

有人可以提示嗎?

謝謝

就像測試一樣,嘗試查看@JsonTypeInfo是否可以工作最簡單。 如果是這樣,那么找出如何與JAXB批注等效。

對於Jackson用戶的Google群組來說,這可能也是一個好問題。

我注意到的一件事,就是它的價值在於,對於許多事情而言,根值是有問題的。 我發現將Root值限制為簡單的POJO很有幫助,並且絕對不要在其中使用ListMap甚至是多態POJO。 原因是Java Type Erasure對通過屬性引用的其他值具有較小的影響,然后具有可用的完整泛型類型。 在這里進行重組可能或不可能,但是我提到這一點是因為它有時可以解決當前的問題。

我得出以下結論,為什么它不起作用。 繼承結構確實匹配“格式良好的文檔”,但是如果進行類型標記,則文檔將具有不同的根元素,具體取決於所使用的子類。 使用自定義XmlTypeAdapter可能可以解決。 在我看來,以下是最簡單的方法。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "RootClass", propOrder = {
        "parentClass"
})
public class RootClass {
    @XmlElements({
            @XmlElement(name = "ChildAClass", type = ChildAClass.class),
            @XmlElement(name = "ChildBClass", type = ChildBClass.class)
    })
    protected ParentClass parentClass;

 ... getters and setters
}



@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParentClass", propOrder = {
        "parentField"
})
public class ParentClass{
    @XmlElement(name = "ParentField")
    protected String parentField;

 ... getters and setters
}


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ChildAClass", propOrder = {
        "childAfield"
})
public class ChildAClass extends ParentClass{

    @XmlElement(name = "ChildAfield")
    protected String childAfield;

 ... getters and setters
}


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ChildBClass", propOrder = {
        "childBfield"
})
public class ChildBClass extends ParentClass{

    @XmlElement(name = "ChildBfield")
    protected String childBfield;

 ... getters and setters
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM