我如何用JAXB编组java.util.List,如JAX-RS(CXF和Jersey)做

似乎最新的JAX-RS可以处理将java.util.List作为XMLRootElement返回的方法,但普通的JAXB不能。 我想模仿CXF和泽西岛正在做的事情。

换句话说,我想列出一个名单,就像CXF和泽西岛一样。 通常,如果您尝试使用JAXB封送列表,则会获得根元素exception。 如何在不必制作包装物的情况下解决这个问题?

编辑:感谢您的答案,但我对@XmlElementWrapper非常熟悉,但这甚至不能模拟JAX-RS正在做的事情。

JAX-RS执行此操作:

@XmlRootElement(name="dog") public class Dog { private String name; public String getName() { return this.name; } //Setter also } 

现在,如果我序列化狗列表:

 serialize(List dogs); 

XML应该是(JAX-RS所做的):

  Rascal  

所以你可以看到我不想为每个域对象创建一个包装器对象。

你能不能简单地添加:

 @XmlElementWrapper(name = "wrapperName") 

无需创建包装器对象。 这将是您的编组XML响应中的路由元素。

我使用以下代码使用自定义可迭代列表,希望这会有所帮助。

 package bindings; import java.io.Serializable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlType @XmlRootElement public class CustomBindList implements Iterable, Serializable { private static final long serialVersionUID = 4449835205581297830L; @XmlElementWrapper(name = "List") @XmlElement(name = "Entry") private final List list = new LinkedList(); public CustomBindList() { } public void add(final V obj) { list.add(obj); } public V get(final int index) { return list.get(index); } @Override public Iterator iterator() { return list.iterator(); } public int size() { return list.size(); } } 

我有一个秘密,它允许我完全避免使用JAXB映射,让一切都神奇地工作。

多年来一直使用这种方法,从不花费5分钟担心编组/解组。 秘诀是……不要使用JAXB。 🙂

在我使用JAX-RS的大多数项目中,我将Jersey配置为使用xstream并让xstream找出如何为我编组/解组。 (或杰森为JSON)

也许有一些理由使用JAXB而不是像xstream / jackson这样的东西,但我还没有找到任何东西。

映射列表可以像这样完成..

 @XmlAccessorType(XmlAccessType.FIELD) @XmlType public class TestRootObject { @XmlElement(name = "testList") private List testList; //getter setter } 

检查jackson,它与JAXB绑定非常兼容,并且使用MappingJsonFactory实际上可以互换使用Java到XML到Java到Json到Java。

我用@XmlJavaTypeAdapter(value = Adapter.class)注释我的集合。 Adapter类从XmlAdapter扩展XmlAdapter键是唯一标识符(un)marshal,值是您的域对象。

也许这可以帮到你。 但是,您必须为每个域对象创建适配器。

我认为Blaise Doughan在这里为这个问题提供了一个很好的解决方案: 是否可以以编程方式配置JAXB?

http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html

虽然在某种程度上稍有不同的用例:

http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html