有以下情况: 具有List字段的类,如:
@XMLType
@XMLAccessType(XMLAccessorType.FIELD)
@XMLRootElement(name = "container")
public class ListContainer {
@XMLElementWrapper(name="elements")
private List<Element> elements = new ArrayList<>();
....
}
Element类是一个带有@XMLRootElement注释的抽象JAXB注释类,如:
@XMLType
@XMLRootElemenent
public abstract class Element {
....
}
这些类定义了某种框架,用户应该能够在自己的JAR包中添加自己的Element类实现。我想要实现的是,在解组后,我将在类ListContainer类实例的实例的元素字段中引入作为框架的扩展。例如,假设在其他ext1.jar中有一个类DummyElement,它位于类路径中,它看起来如下:
@XMLType
@XMLRootElement(name = "dummy")
public class DummyElement extends Element {
....
}
在ext2.jar中我会有EasyElement,如:
@XMLType
@XMLRootElement(name = "easy")
public class EasyElement extends Element {
...
}
在xml那里我会有类似的地方:
<container>
<elements>
<dummy>....</dummy>
<easy>...</easy>
<easy>....</easy>
<dummy>...</dummy>
</elements>
</container>
预期的结果应该是,ListContainer类的解组实例在元素字段中将有2个DummyElement实例和2个EasyElement实例。
到目前为止,如果我将ListContainer类注释为这样 - 我将无法列出任何内容。如果我用@XMLAnyElement注释(lax = true)那么我将有ElementNSImpl实例。
提前感谢您的想法。
答案 0 :(得分:1)
更新:
解决方案是控制JAXBContext的创建。我创建了服务接口,它为我提供了上下文所需的类列表,如:
public interface XMLContextProvider {
Set<Class> getJAXBContextClasses();
}
然后我在框架中创建了一个实现此接口的类,并从框架的一侧列出了我需要的所有类。扩展也是如此。在META-INF / services中注册的类 - 请参阅ServiceLoader。然后我创建了一个实用程序类,它利用ServiceLoader查找所有提供程序,并使用从所有提供程序收集的所有类的列表创建JAXBContext。在这种背景下,Marshal和Unmarshal是可能的。另外,当我使用JAX-RS时,我为JAXBContext创建了一个解析器:
@Provider
public class XMLContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public XMLContextResolver() {
ctx = <here goes call to utility class>
}
@Override
public JAXBContext getContext(Class<?> type) {
if (this.classes.contains(type)) {
return this.ctx;
}
return null;
}
}