JAXB:List <Object>项的XmlAdapter

Pau*_*sak 8 java jaxb jaxb2

有人知道如何将自定义附加XmlAdapter到异构列表中包含的对象(如List)吗?例如 - 假设我们有一个带有miscelaneous对象列表的容器类:

@XmlRootElement(name = "container")
public class Container {
    private List<Object> values = new ArrayList<Object>();

    @XmlElement(name = "value")
    public List<Object> getValues() {
        return values;
    }

    public void setValues(List<Object> values) {
        this.values = values;
    }   
}
Run Code Online (Sandbox Code Playgroud)

如果我们放String-s,Integer-s等,它们将默认映射.现在假设我们想要放置一个自定义对象:

public class MyObject {
    //some properties go here   
}
Run Code Online (Sandbox Code Playgroud)

显而易见的解决方案是编写自定义适配器:

public class MyObjectAdapter extends XmlAdapter<String, MyObject> {
    //marshalling/unmarshalling
}
Run Code Online (Sandbox Code Playgroud)

但遗憾的是它不适用于包级别@XmlJavaTypeAdapter- 适配器从未调用过,因此编组失败.我不能getValues()直接应用它,因为可以有其他类型的对象. @XmlJavaTypeAdapter只有在Container中有MyObject类型的字段(也包含包级别注释)时才有效:

public class Container {
    private MyObject myObject;
}
Run Code Online (Sandbox Code Playgroud)

但这不是我想要的 - 我想要一个任意对象列表.我正在使用标准的Sun的JAXB实现:

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.3-1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

任何想法如何进行映射?

PS:一个小小的澄清 - 我想避免MyObject使用JAXB注释进行注释.它可能是来自第三方图书馆的课程,不受我的控制.所以任何改变都应该在...之外MyObject.

mvi*_*fer 1

您可以尝试更改您的MyObjectAdapter以便扩展XmlAdapter<String, List<Object>>. 所以它应该看起来像这样:

public class MyObjectAdapter extends XmlAdapter<String, List<Object>> {
    //marshalling/unmarshalling
}
Run Code Online (Sandbox Code Playgroud)

当您还将 XmlJavaTypeAdapter 注释添加到Container类中的 getter 时,它应该可以工作。

@XmlRootElement(name = "container")
public class Container {
    private ArrayList<Object> values = new ArrayList<Object>();

    @XmlElement(name = "value")
    @XmlJavaTypeAdapter(MyObjectAdapter.class)
    public ArrayList<Object> getValues() {
        return values;
    }

    public void setValues(ArrayList<Object> values) {
        this.values = values;
    }   
}
Run Code Online (Sandbox Code Playgroud)