加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在javax.xml.bind中创建一个通用集合

发布时间:2020-12-15 02:24:32 所属栏目:Java 来源:网络整理
导读:在我编写的REST服务器中,我有几个集合类,它们包含从我的服务返回的单个项目: @XmlAccessorType(XmlAccessType.NONE)@XmlRootElement(name = "person_collection")public final class PersonCollection { @XmlElement(name = "person") protected final List
在我编写的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?顺便说一句,我正在使用RestEasy 1.2.1 GA作为JAX-RS前端.

更新(对于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.

解决方法

反思问题

以下是需要进行的反射测试.我相信类型擦除是阻止这种情况发生的原因:

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class TestReflection extends AbstractCollection<String> {

    private List<Integer> childCollection = new ArrayList<Integer>();


    public List<Integer> getChildCollection() {
        return childCollection;
    }

    public static void main(final String[] args) throws Exception {
        final TestReflection testReflection = new TestReflection();

        final Class<?> cls = testReflection.getClass();
        Method method1 = cls.getMethod("getChildCollection",new Class[] {});
        System.out.println(method1.getGenericReturnType());

        Method method2 = cls.getMethod("getCollection",new Class[] {});
        System.out.println(method2.getGenericReturnType());
   }

}

上面的代码将输出如下所示的内容.这是因为“getCollection”方法位于AbstractCollection的上下文中,而不是TestReflection.这是为了确保Java二进制文件的向后兼容性:

java.util.List<java.lang.Integer>
java.util.List<T>

替代方法

如果集合中的项目将使用@XmlRootElement注释,那么您可以使用以下内容实现您想要的操作:

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;

public abstract class AbstractCollection<T> {

    protected List<T> collection = new ArrayList<T>();

    @XmlAnyElement(lax=true)
    public List<T> getCollection() {
        return collection;
    }

}

假设Person看起来如下:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {

}

然后是以下演示代码:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(PersonCollection.class,Person.class);

        PersonCollection pc = new PersonCollection();
        pc.getCollection().add(new Person());
        pc.getCollection().add(new Person());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
        marshaller.marshal(pc,System.out);
    }

}

会产生:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person_collection>
    <person/>
    <person/>
</person_collection>

有关更多信息,请参阅

> http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读