【发布时间】:2011-03-22 12:49:47
【问题描述】:
在我编写的 REST 服务器中,我有几个集合类,用于包装要从我的服务返回的单个项目:
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "person_collection")
public final class PersonCollection {
@XmlElement(name = "person")
protected final List<Person> collection = new ArrayList<Person>();
public List<Person> getCollection() {
return collection;
}
}
我想重构这些以使用泛型,以便可以在超类中实现样板代码:
public abstract class AbstractCollection<T> {
protected final List<T> collection = new ArrayList<T>();
public List<T> getCollection() {
return collection;
}
}
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "person_collection")
public final class PersonCollection extends AbstractCollection<Person> {}
如何在超类集合上设置@XmlElement 注解?我正在考虑涉及@XmlJavaTypeAdapter 和反射的东西,但希望有更简单的东西。如何创建JAXBContext?顺便说一句,我在 JAX-RS 前端使用 RestEasy 1.2.1 GA。
更新(对于 Andrew White):以下代码演示了获取类型参数的 Class 对象:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;
public class TestReflection
extends AbstractCollection<String> {
public static void main(final String[] args) {
final TestReflection testReflection = new TestReflection();
final Class<?> cls = testReflection.getClass();
final Type[] types = ((ParameterizedType) cls.getGenericSuperclass()).getActualTypeArguments();
for (final Type t : types) {
final Class<?> typeVariable = (Class<?>) t;
System.out.println(typeVariable.getCanonicalName());
}
}
}
class AbstractCollection<T> {
protected List<T> collection = new ArrayList<T>();
}
这是输出:java.lang.String。
【问题讨论】:
-
您不必在
@XmlElement上指定name属性,因此您只需将@XmlElement添加到AbstractCollection.collection,并让JAXB 推断元素名称。 -
@skaffman:它不工作。我收到了
javax.xml.bind.JAXBException: class com.example.Person nor any of its super class is known to this context -
嗯,这是您创建 JAXB 上下文的方式的错误。将其添加到您的问题中,我会发布答案。
-
@skaffman:已添加。见上文:-)。
-
+1 好问题 - 目前正在使用 EclipseLink JAXB (MOXy) 调试此问题。