JAXB marshal Set <Object>

Edu*_*cia 5 java jaxb marshalling

我有一个与此类似的对象:

public class Obj {
    @XmlElement(name="value")
    public Set<Object> values;
}
Run Code Online (Sandbox Code Playgroud)

编组时,这会生成一个xml,如:

<Obj>
    <value xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema">2009-02-14T00:31:30.001+01:00</value>
    <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">test</value>
</Obj>
Run Code Online (Sandbox Code Playgroud)

但是,我想改变一些值(比如用于序列化DateTimestamp对象的日期格式),并且还要摆脱烦人的xsi属性(但这不是真正的要求,我可以忍受它)

我试着添加@XmlJavaTypeAdaptervalues,但在适配器我得到充分Set<Object>的适应,而不是单一的元素.我也试过用包适配器,但是,我的SetObject,我不能忍受的@XmlJavaTypeAdapter(type)属性.

此外,我已经尝试过@XmlJavaTypeAdapter(value=MyAdapter.class, type=Timestamp.class)只获取我想要的Object内部值的适配器.

所以问题是,是否有人知道如何让适配器为此工作?或者,每次DateTimestamp序列化对象时,都可以更改日期格式?

提前致谢!

EdC*_*EdC 1

@XmlJavaTypeAdapter必须在包级别指定 type 属性。当以这种方式使用时,它表明指定包中该类型的所有用法都使用XmlAdapter. 例如,如果你有一个package-info.java喜欢

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdaptor(type=Timestamp.class, value=MyAdapter.class)
})
package org.example;
Run Code Online (Sandbox Code Playgroud)

然后是该包中带有时间戳字段的类。

package org.example;
public class Obj {
    public Timestamp aTimestamp;
}
Run Code Online (Sandbox Code Playgroud)

指定的适配器将用于转换时间戳。我怀疑这对你的情况有用Set<Object>,但我自己还没有尝试过。

使用该属性的原因xsi:type是 JAX-B 喜欢生成可以反序列化的 XML,因此它需要指示它是什么类型,否则它只能将所有内容解析回字符串。您可以通过使用@XmlElementRef注释创建架构替换组来摆脱此属性,但在这种情况下,将使用不同的元素名称生成 XML。例如

public class Obj {
    @XmlElementRefs({
        @XmlElementRef(type=String.class, name="string"),
        @XmlElementRef(type=Timestamp.class, name="timestamp")
    })
    public Set<Object> value;
}
Run Code Online (Sandbox Code Playgroud)

如果集合中有时间戳和字符串,将生成以下 XML 结构。在这种情况下,该xsi:type属性是不必要的,因为 JAX-B 可以根据元素名称判断要创建什么类型。

<Obj>
    <timestamp>2009-02-14T00:31:30.001+01:00</timestamp>
    <string>test</string>
</Obj>
Run Code Online (Sandbox Code Playgroud)

如果您打算采用这种方法,我强烈建议您使用@XmlElementWrapper注释来包装所有设置项。

如果您所追求的只是一组简单的字符串,您不关心将其反序列化回具有正确类型的 Java(或任何其他)对象,那么最简单的解决方案是使用一个 XmlAdapter,它只将完整的字符串Set<Object>适应aSet<String>并自行处理转换。