13

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

换句话说,我想编组一个列表,就像 CXF 和 Jersey 一样。通常,如果您尝试使用 JAXB 编组列表,则会收到 Root Element 异常。我如何在不必制作包装对象的情况下解决这个问题?

编辑:感谢您提供的许多答案,但我对@XmlElementWrapper 非常熟悉,但这甚至无法模拟 JAX-RS 正在做什么。

JAX-RS 这样做:

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

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

serialize(List<Dog> dogs);

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

<dogs>
    <dog><name>Rascal</name></dog>
</dogs>

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

4

7 回答 7

7

Could you not simply add:

@XmlElementWrapper(name = "wrapperName")

No need to make a wrapper object. This will then be the route element in your marshalled XML response.

于 2011-12-13T16:35:45.550 回答
3

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

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<V> implements Iterable<V>, Serializable {
        private static final long serialVersionUID = 4449835205581297830L;

        @XmlElementWrapper(name = "List")
        @XmlElement(name = "Entry")
    private final List<V> list = new LinkedList<V>();

    public CustomBindList() {
    }

    public void add(final V obj) {
            list.add(obj);
    }

    public V get(final int index) {
        return list.get(index);
    }

    @Override
    public Iterator<V> iterator() {
        return list.iterator();
    }

    public int size() {
        return list.size();
    }
}
于 2012-01-21T05:49:13.260 回答
3

我有一个秘密可以让我完全避免使用 JAXB 映射并让一切都神奇地工作。

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

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

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

于 2012-05-02T20:10:47.653 回答
1

mapping a List can be done like this..

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public class TestRootObject {

  @XmlElement(name = "testList") 
  private List<TestObj> testList;

  //getter setter
}
于 2012-04-21T05:55:56.130 回答
1

我相信 Blaise Doughan 在这里为这个问题提供了一个很好的解决方案:Is it possible to programmatically configure JAXB?

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

尽管用例略有不同,但在这里有些不同:

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

于 2015-03-09T17:57:07.557 回答
1

我用@XmlJavaTypeAdapter(value = Adapter.class). Adapter 类从XmlAdapter<key, value>key 扩展为 (un)marshal 的唯一标识符,而 value 是您的域对象。

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

于 2012-06-01T11:45:57.537 回答
1

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

于 2012-05-11T11:56:02.250 回答