我有一个扩展ParentClass的类(ChildClass(。解组时,我从setPropFromElementList((中得到一个异常,即我传递的值不在列表中,即使它确实存在于列表中。我相信这个问题是由JAXB试图在设置子元素之前设置父元素的属性引起的。
我看到了各种博客文章和问题,建议将父类设置为Transient,然后在子类上使用propOrder(也包括父类中的元素(。这对我没有帮助——我收到了非法公告异常。
有什么想法吗?(下面是示例代码-这不是我使用的精确的代码,所以我不能100%确定它会编译。然而,它确实显示了我在真实代码中所做的事情。(
ParentClass.java
@XmlTransient //on the entire class - not shown here
private String propFromElementList
@XmlAttribute
String getPropFromElementList() {
return this.propFromElementList;
}
void setPropFromElementList(String value) {
checkThatValueIsInList(value);
this.propFromElementList = value;
}
protected abstract void checkThatValueIsInList(String value);
ChildClass.java扩展ParentClass
@XmlType(propOrder={"list","propFromElementList"}(
private String[] list;
@XmlElement
public String[] getList() {
return this.list;
}
public void setList(final String... list) {
this.list = list;
}
@Override
protected void checkThatValueIsInList(String value) {
//search for String and throw RuntimeException if not found
}
XML
<child propFromElementList="A">
<list>A B C D</list>
</child>
更新
在使用继承时,有没有一种方法可以确保我的jaxb元素设置在属性之前?
您无法控制JAXB(JSR-222(实现填充域模型的顺序。JAXB impl最喜欢填充对象模型,因为它在解组操作期间执行XML文档的深度优先遍历。这意味着,属性通常会在任何子元素之前进行处理,这似乎是导致用例中出现问题的原因。
您可能需要考虑将验证逻辑移到setPropFromElementList
方法之外,并将其放入afterUnmarshal
方法中。
- http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshalEventCallback
原始答案
@XmlType
上的propOrder
设置仅在编组时使用。不能在@XmlType
的propOrder
中包含用@XmlAttribute映射的属性。既然你有:
@XmlAttribute
String getPropFromElementList() {
return this.propFromElementList;
}
则propFromElementList
不能出现在仅针对非属性节点的propOrder
中。