Как я могу создать 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>
Итак, вы можете видеть, что я не хочу создавать объект-оболочку для каждого объекта домена.
Ответы
Ответ 1
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
Ответ 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), и это значение является вашим объектом домена.
Возможно, это поможет вам. Однако вам нужно создать адаптер для каждого объекта домена.