Staying DRY with JAXB

纵饮孤独 提交于 2019-12-05 16:23:12
bdoughan

The issue you are seeing is due to bugs in both the Metro (reference implementation) and EclipseLink MOXy JAXB implementations. The relevant MOXy bug is:

One thing to note about your use case is that due to type erasure, a JAXB implementation is going to treat the value property as type Object. This means that marshal operations will work for you, but an unmarshal operation will return the value as a String. This is why if the value field was annotated with @XmlElement that xsi:type information would be included to preserve the type information:

MOXy Workaround

You workaround the MOXy bug by leveraging the following XmlAdapter:

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ObjectAdapter extends XmlAdapter<Object, Object> {

    @Override
    public Object unmarshal(Object v) throws Exception {
        return v;
    }

    @Override
    public Object marshal(Object v) throws Exception {
        return v;
    }

}

The XML Adapter is registered on your property as follows:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlTransient
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(Foo.class)
abstract class Wrapper<T> {

    @XmlAttribute
    @XmlJavaTypeAdapter(ObjectAdapter.class)
    private T value;

    Wrapper() {} // default ctor for JAXB

    public Wrapper(T t) {
        value = t;
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!