我使用JAXB注释面临Jackson的ObjectMapper问题。具体来说,我有接口通用信息的集合,虽然我可以从XML反序列化输入,但Jackson(使用JAXB introspector)是不可能的。也许我只是缺少一些配置属性或JAXB注释?问题是“抽象类型只能使用其他类型信息进行实例化”,我认为带有类型信息的@XmlElementRef(或@XmlElement)将处理这个问题,但显而易见它没有。
请注意,如果可能,我希望仅使用JAXB注释。 例如。使用@JsonTypeInfo或@JsonDeserialize将是最后一件事。
IEntry.java:
@XmlSeeAlso(Entry.class)
public interface IEntry {
String getValue();
}
Entry.java:
@XmlRootElement(name = "entry")
public class Entry implements IEntry {
@XmlElement(name = "value")
String value;
public Entry() {
}
public Entry(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Aggregator.java:
@XmlRootElement(name = "aggregator")
public class Aggregator {
@XmlElementRef(type = Entry.class)
private Set<IEntry> entries;
public Aggregator() {
}
public Aggregator(Set<IEntry> entries) {
this.entries = entries;
}
public Set<IEntry> getEntries() {
return entries;
}
}
测试方法:
@Test
public void testSerialization() throws Exception {
ObjectMapper om = new ObjectMapper();
AnnotationIntrospector intr = new JaxbAnnotationIntrospector();
om.getDeserializationConfig().withAnnotationIntrospector(intr);
String json = "{\"entries\":[{\"value\":\"X\"},{\"value\":\"Y\"},{\"value\":\"Z\"}]}\";\n}";
Aggregator agr = om.readValue(json, Aggregator.class);
}
感谢所有回复
答案 0 :(得分:2)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
我不确定Jackson是否支持此用例,但您似乎错误地使用了@XmlElementRef
。使用@XmlElementRef
时,与该类关联的根元素名称用于确定要实例化的实例。如果您的示例中节点entries
与@XmlRootElement(name="entry")
注释不匹配。
您可以尝试以下选项之一(它们都适用于MOXy的JSON绑定,请参阅:http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html):
选项1 - 更改@XMLRootElement
上的Entry
@XmlRootElement(name = "entries")
public class Entry implements IEntry {
@XmlElement(name = "value")
String value;
public Entry() {
}
public Entry(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
选项#2 - 更改JSON文档
{"entry":[{"value":"X"},{"value":"Y"},{"value":"Z"}]}}
选项#3 - 使用@XMLElement
代替@XMLElementRef
如果使用@XmlElement
注释,则可以在字段/属性上指定节点名称应该是什么,而不是依赖于@XmlRootElement
注释。此外,如果您注释字段,则应在类型级别指定@XmlAccessorType(XmlAccessType.FIELD)
。
import java.util.Set;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "aggregator")
@XmlAccessorType(XmlAccessType.FIELD)
public class Aggregator {
@XmlElement(type = Entry.class)
private Set<IEntry> entries;
public Aggregator() {
}
public Aggregator(Set<IEntry> entries) {
this.entries = entries;
}
public Set<IEntry> getEntries() {
return entries;
}
}
了解更多信息
答案 1 :(得分:1)
import org.codehaus.jackson.map.annotate.JsonDeserialize;
@JsonDeserialize(as = Entry.class)
public interface IEntry {
String getValue();
}