3

我必须解析一个复杂的 XML 文档。我的模型中的一些类实现了接口HasDate

interface HasDate {
    public void setDate(Date date);
}

创建解组器的日期是已知的:

// here I know the date.
JAXBContext ctx = JAXBContext.newInstance("com.mycompany.mymodel");
Unmarshaller unmarshaller = ctx.createUnmarshaller();
unmarshaller.unmarshal(input);

我想调用在 JAXB 解析文档时setDate()实现的每个类实例。HasDate

这是我自己知道的 2 个解决方案:我可以将每个相关类注释如下:

@XmlType(factoryClass = ObjectFactory.class, factoryMethod = "createMyObject")

该方法createMyObject()将调用setDate(). 这个解决方案的问题是它createMyObject()必须是静态的。将信息设置为静态成员会使解决方案不是线程安全的。

作为此解决方案的一种变体,我可以将日期放在ThreadLocal解析之前。createMyObject()将从中读取日期 ThreadLocal并调用setDate(). 这个解决方案是线程安全的,但看起来像一个补丁。

其他解决方案是使用反射发现由 JAXB 创建的对象图,递归遍历它并setDate()在需要时调用。该解决方案是线程安全的,但需要一些实施工作并且需要在未来进行维护。

我想知道 JAXB 是否有针对此问题的其他内置解决方案。

4

2 回答 2

2

您可以实现一个Unmarshaller.Listener并将其设置在Unmarshaller. 然后在afterUnmarshal方法上,如果目标类是一个实例,HasDate那么你可以setDate在它上面调用方法。

于 2012-08-23T17:52:25.220 回答
2

我建议@XmlAdapter对所有实现HasDate接口的类使用。这使您的用例明确且类型安全。您可以拥有一个能够从 ThreadLocal 中查找日期的基本适配器。

XmlAdapter:JAXB 的秘密武器

如果此选项不起作用,那么我喜欢在afterUnmarshall生命周期方法中调用反射方法。

于 2012-08-23T17:29:54.347 回答