jackson JAXB注释 - 根元素的继承映射

时间:2015-04-10 20:45:07

标签: java json serialization jaxb jackson

我遵循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( ...

我认为这里缺少一些类型元数据用于propper类型推断和反序列化。我当时正在寻找@JsonTypeInfo,但我仅限于JAXB。我尝试了@XmlElements jaxb注释,但是无法使它工作。

有人可以提示吗?

THX

2 个答案:

答案 0 :(得分:0)

尝试查看@JsonTypeInfo是否有效可能是最简单的,就像测试一样。如果确实如此,那么弄清楚如何使用JAXB注释获得相同的效果。

对于杰克逊用户谷歌小组来说这也许是一个很好的问题。

我注意到的一件事,就是值得的是,根值对许多事情都是有问题的。我发现将Root值限制为简单的POJO很有帮助,并且从不在那里使用ListMap甚至多态POJO。这样做的原因是Java Type Erasure对通过属性引用的其他值的影响要小得多,然后具有完整的泛型类型。 这里的重组可能会或可能不会,但我提到这一点,因为它有时解决了手头的问题。

答案 1 :(得分:0)

我接下来总结为什么那不起作用。继承结构与“格式良好的文档”匹配,但在类型标记的情况下,文档将具有不同的根元素,具体取决于使用的子类。它可能通过使用自定义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
}