Отключить специальную обработку для реализации List<T> во время маршалинга JAXB

У меня есть @XmlTransient класс называется ListBase<T> который реализует List<T>, Затем я подкласс этого списка в @XmlType StringList, @XmlType PersonList, так далее.

Кажется, что JAXB обрабатывает такие классы особым образом, например, когда экземпляр этого класса является членом какого-то другого класса, тогда этот член маршалируется как

<xs:element maxOccurs="unbounded" type="whatever the type of T" .../>

вместо

<xs:element type="type of my list implementor" .../>`

то есть содержимое списка маршалируется вместо самого списка.

Класс ListBase<T> инвентарь List<T> инкапсуляцией, то есть имеет поле типа List<T> и это выставляет это поле через аксессоры, помеченные как @XmlElement так что внутренний список маршалируется с типом. Если я удалю implements List<T> из моего списка разработчиков я получаю второй (желательный) вариант, но это означает изменение остальной части приложения, чтобы оно осознавало инкапсуляцию.

Как я могу отключить специальную обработку моего разработчика List, чтобы он маршалировался как любой другой сложный тип, не относящийся к коллекции?

@XmlTransient
public abstract class ListBase<T> implements List<T> {
    protected List<T> list;

    public ListBase(List<T> list) {
        this.list = list;
    }

    public ListBase() {
        this(new ArrayList<T>());
    }

    public abstract List<T> getList();

    public abstract void setList(List<T> value);

    //The rest is List<T> implementation using encapsulation of this.list
    //...
}

@XmlType(name = "ArrayOfstring", namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays")
@XmlAccessorType(XmlAccessType.NONE)
public class StringList extends ListBase<String> {
    public StringList(List<String> list) {
        super(list);
    }

    public StringList() {
        super();
    }

    @XmlElement(name = "string")
    public List<String> getList() {
        return list;
    }

    public void setList(List<String> value) {
        this.list = value;
    }
}

1 ответ

Решение

Примечание: я являюсь лидером EclipseLink JAXB (MOXy) и являюсь членом экспертной группы JAXB (JSR-222).

Если вы используете MOXy в качестве вашего JAXB-провайдера, вы используете внешний файл привязки для переопределения суперкласса ваших типов.

<?xml version="1.0"?>
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum116436770">
    <java-types>
        <java-type name="StringList" super-type="java.lang.Object" />
    </java-types>
</xml-bindings>

Связанный вопрос

Для дополнительной информации

Другие вопросы по тегам