jackson JAXB 注释 - 根元素的继承映射
jackson JAXB annotations - inheritance mapping at the root element
我有以下 Jaxb 注释 class 层次结构,包括文档根元素的继承:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParentClass", propOrder = {
"parentField"
})
public class ParentClass{
@XmlElement(name = "ParentField")
protected String parentField;
getters and setters here
}
孩子A类:
@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
}
这是非常简单的 class 层次结构。比起我有一个简单的测试,我在其中序列化了一个 ChildAClass 并尝试反序列化为一个 ParentClass。我希望 propper class 被反序列化并向上转换为 ParentClass。我想这是一个有效的用例。
连载后的文档如下,没什么特别的
{
"ChildAfield": "child A field",
"ParentField": "parent from child A"
}
但是当我尝试 de-serialize :
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 很有帮助,并且永远不要在那里使用 List
、Map
甚至多态 POJO。这样做的原因是 Java 类型擦除对通过属性引用的其他值的影响要小得多,然后具有完整的通用类型可用。
此处重组可能可行也可能不可行,但我提到这一点是因为它有时可以解决手头的问题。
我得出以下结论,为什么这不起作用。继承结构确实匹配 "well formed document",但在类型标记的情况下,文档将根据使用的子类具有不同的根元素。它可能可以通过使用自定义 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
}
我有以下 Jaxb 注释 class 层次结构,包括文档根元素的继承:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParentClass", propOrder = {
"parentField"
})
public class ParentClass{
@XmlElement(name = "ParentField")
protected String parentField;
getters and setters here
}
孩子A类:
@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
}
这是非常简单的 class 层次结构。比起我有一个简单的测试,我在其中序列化了一个 ChildAClass 并尝试反序列化为一个 ParentClass。我希望 propper class 被反序列化并向上转换为 ParentClass。我想这是一个有效的用例。
连载后的文档如下,没什么特别的
{
"ChildAfield": "child A field",
"ParentField": "parent from child A"
}
但是当我尝试 de-serialize :
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 很有帮助,并且永远不要在那里使用 List
、Map
甚至多态 POJO。这样做的原因是 Java 类型擦除对通过属性引用的其他值的影响要小得多,然后具有完整的通用类型可用。
此处重组可能可行也可能不可行,但我提到这一点是因为它有时可以解决手头的问题。
我得出以下结论,为什么这不起作用。继承结构确实匹配 "well formed document",但在类型标记的情况下,文档将根据使用的子类具有不同的根元素。它可能可以通过使用自定义 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
}