我有以下内容:
class A{
@XmlElement
String name;
//getters and setters
}
和
class B extends A{
@XmlElement
String height;
//getters and setters
}
最后我有
@XmlRootElement
class P{
@XmlElement
List<A> things;
//getters and setters
}
如果我这样做
List<A> l = new ArrayList<A>();
l.add(new B('hello', 20)) //Add new B with height of 20 and name hello
P p = new P();
p.setThings(l); //Set things to list of B's.
并且编组P,我只将场地作为事物的一部分而非高度。
我知道我可以在A中添加@XmlSeeAlso(B.class)并且它都可以工作。
但问题是我不知道B以外的所有扩展类,因为A可能会在运行时扩展。
如何在运行时动态定义@XmlSeeAlso?
答案 0 :(得分:2)
这取决于您创建JAXBContext的方式。可以使用所有类的显式列表调用newInstance method,该方法的文档也提供了类似的示例。
客户端应用程序必须提供新上下文对象需要识别的类列表。不仅新的上下文将识别指定的所有类,而且它还将识别从指定的类静态直接/间接引用的任何类。引用类的子类和@XmlTransient引用的类未在JAXBContext中注册。例如,在下面的Java代码中,如果你执行newInstance(Foo.class),新创建的JAXBContext将识别Foo和Bar,但不识别Zot或FooBar:
class Foo {
@XmlTransient FooBar c;
Bar b;
}
class Bar { int x; }
class Zot extends Bar { int y; }
class FooBar { }
修改:如果您至少知道潜在jaxb类的包名称,也可以create a context given a context path。
如果无法实现上述目的,您还可以根据要序列化的对象在运行时创建类列表。我认为最好尝试重构代码以使其不必要。以下代码未经测试:
Set<Class> classes = new HashSet<Class>();
classes.add(p.getClass());
for (A a : p.getThings()) {
classes.add(a.getClass());
}
JAXBContext context = JAXBContext.newInstance(classes.toArray(new Class[classes.size()]));
答案 1 :(得分:1)
请注意,@XmlSeeAlso
也可以在网络服务上添加注释,请参阅此帖:http://weblogs.java.net/blog/kohlert/archive/2006/10/jaxws_and_type.html
如果您的基类无法访问子类(例如,因为它们位于不同的模块中),但您的Web服务具有访问权限,则此功能非常有用。