javajaxbjax-wscxfjax-ws-customization

Disable special treatment of a List<T> implementor during JAXB marshaling


I have a @XmlTransient class called ListBase<T> which implements List<T>. I then subclass that list into @XmlType StringList, @XmlType PersonList, etc.

It seems that JAXB treats such classes in a special way, such as when an instance of that class is a member of some other class, then that member gets marshaled as

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

instead of

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

that is, the contents of the list gets marshaled instead of the list itself.

The class ListBase<T> implements List<T> by encapsulation, i.e. it has a field of type List<T> and it exposes that field through accessors marked as @XmlElement so that the inner list gets marshaled with the type. If I remove implements List<T> from my list implementor then I get the second (desired) variant but that means modifying rest of the application so that it's aware of encapsulation.

How can I disable special treatment of my List implementor such that it gets marshaled as any other non-collection complex type?

@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;
    }
}

Solution

  • Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

    If you are using MOXy as your JAXB provider then you leverage the external binding file to override the super class of your types.

    <?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>
    

    Related Question

    For More Information