自定义JAXB unmarshall进程的error handling

假设我有一个描述根元素类Root的模式,其中包含一个List ,其中Entry类具有必需的字段名称。

以下是代码中的外观:

 @XmlRootElement class Root{ @XmlElement(name="entry") public List entries = Lists.newArrayList(); } @XmlRootElement class Entry{ @XmlElement(name="name",required=true) public String name; } 

如果我提供以下XML用于解组:

   ekeren     

我有一个问题,因为第二个条目不包含名称。 所以unmarshall产生null

有没有办法自定义JAXB以解组只包含“好”条目的Root对象?

您可以添加神奇的AfterUnmarshal方法来处理空条目:

 @XmlRootElement class Root{ @XmlElement(name="entry") public List entries = Lists.newArrayList(); void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) { Iterator iter = entries.iterator(); while (iter.hasNext()) { if (iter.next().name == null) iter.remove(); } } } 

编辑:

不确定这是否更适合你,但也许它有帮助。 您也可以使用Pacher,例如,如果不是您需要修复/validation结果的所有对象都可以在afterUnmarshal(..)中使用

完成所有解析后运行UnmarshallingContext。 主要用于解析转发IDREF,但它可以运行任何操作。 (Javadoc中)

这是一个例子:

 @XmlRootElement class Entry{ @XmlElement(name="name",required=true) public String name; private boolean isValidEntry() { return name != null; } void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) { if (!isValidEntry()) { // entry not yet added to parent - use a patcher UnmarshallingContext.getInstance().addPatcher(new Patcher() { public void run() throws SAXException { ((Root)parent).removeEntry(this); } }); } } } 

我不会过分滥用它,不仅因为它只是Sun-only API。

但是,如果您真的在寻找可配置的东西,而这些东西不是编组对象本身的代码的一部分。 解组后最好看一些东西。 我想知道Bean Validation(JSR 303)是否适合你,例如使用Hibernate Validator (不要被名字吓倒,你不需要Hibernate ORM来使用它)。 我自己没有使用它,但使用(新)标准进行validation听起来合理,不是吗?