Как я могу создать java.util.List с JAXB, например JAX-RS (CXF и Джерси)

Кажется, что последний JAX-RS может обрабатывать методы, возвращающие java.util.List как XMLRootElement, но обычный JAXB не может. Я хотел бы подражать тому, что делают CXF и Jersey.

Другими словами, я хотел бы Маршал Список и так же, как CXF и Джерси. Обычно, если вы пытаетесь упорядочить список с помощью JAXB, вы получаете исключение Root Element. Как мне обойти это без необходимости создания оберточного объекта?

EDIT: Спасибо за много ответов, но я очень хорошо знаком с @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>

Итак, вы можете видеть, что я не хочу создавать объект-оболочку для каждого объекта домена.

Ответы

Ответ 2

Не могли бы вы просто добавить:

@XmlElementWrapper(name = "wrapperName")

Не нужно создавать объект-оболочку. Это будет элемент маршрута в вашем ответе XML с сортировкой.

Ответ 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();
    }
}

Ответ 4

У меня есть секрет, который позволяет мне избегать завинчивания с помощью JAXB-сопоставлений полностью и все работает магически.

Использовать этот подход в течение многих лет, никогда не тратил даже 5 минут, беспокоясь о сортировке/разборке. Секрет... не использовать JAXB.:)

В большинстве моих проектов, которые используют JAX-RS, я настраиваю Джерси для использования xstream и позволяю xstream определять, как маршал /unmarshal для меня. (или Джексон для JSON)

Возможно, есть несколько причин использовать JAXB вместо чего-то вроде xstream/jackson, но я еще не нашел его.

Ответ 5

отображение списка может быть выполнено следующим образом.

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

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

  //getter setter
}

Ответ 6

проверьте Jackson out, он очень совместим с привязками JAXB и с помощью MappingJsonFactory вы можете на самом деле взаимозаменяемо использовать Java для XML для Java для Json для Java.

Ответ 7

Я комментирую свои коллекции с помощью @XmlJavaTypeAdapter(value = Adapter.class). Класс Adapter распространяется от XmlAdapter<key, value>, ключ является уникальным идентификатором маркера (un), и это значение является вашим объектом домена.

Возможно, это поможет вам. Однако вам нужно создать адаптер для каждого объекта домена.