Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java jackson JAXB注释-根元素的继承映射_Java_Json_Serialization_Jaxb_Jackson - Fatal编程技术网

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

Java jackson JAXB注释-根元素的继承映射,java,json,serialization,jaxb,jackson,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 s

我有以下Jaxb注释类层次结构,包括文档根元素的继承:

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

  getters and setters here
}
儿童类:

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

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

  getters and setters here
}
儿童班:

@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

像测试一样,尝试查看
@JsonTypeInfo
是否有效可能是最容易的。如果是这样的话,那么请找出如何与JAXB注释等效

对于杰克逊的用户谷歌集团来说,这可能也是一个好问题

我注意到的一件事是,根值在很多事情上都是有问题的。我发现将根值限制为简单的POJO很有帮助,并且永远不要在那里使用
列表
映射
,甚至多态POJO。这样做的原因是Java类型擦除对通过属性引用的其他值的影响要小得多,这些值可以使用完整的泛型类型。
重组在这里可能是可能的,也可能是不可能的,但我提到这一点,因为它有时可以解决手头的问题。

我得出以下结论,为什么这不起作用。继承结构与“格式良好的文档”匹配,但在类型标记的情况下,文档将具有不同的根元素,具体取决于使用的子类。使用定制的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
}