JAXB使用新JAR添加带注释的类

时间:2017-07-12 15:09:56

标签: java xml jaxb annotations

有以下情况: 具有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实例。

提前感谢您的想法。

1 个答案:

答案 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;
    }
}