JAXB marshal Set <object> </object>

时间:2011-06-10 15:06:45

标签: java jaxb marshalling

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

public class Obj {
    @XmlElement(name="value")
    public Set<Object> values;
}

编组时,这会产生一个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>

但是,我想更改其中的一些值(比如用于序列化DateTimestamp个对象的日期格式),还要删除烦人的xsi属性(但是这不是一个真正的要求,我可以忍受这一点)

我尝试将@XmlJavaTypeAdapter添加到values,但在适配器中,我得到了完整的Set<Object>以适应,而不是单个元素。我也尝试过使用套餐适配器,但由于我的Set适用于Object,我无法使用@XmlJavaTypeAdapter(type)属性。

另外,我尝试使用@XmlJavaTypeAdapter(value=MyAdapter.class, type=Timestamp.class)来获取我想要的Object内部值的适配器。

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

提前致谢!

1 个答案:

答案 0 :(得分:1)

必须在包级别指定具有type属性的

@XmlJavaTypeAdapter。以这种方式使用时,它表示使用XmlAdapter转换指定包中该类型的所有用法。例如。如果您有package-info.java喜欢

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdaptor(type=Timestamp.class, value=MyAdapter.class)
})
package org.example;

然后是该包中带有Timestamp字段的类。

package org.example;
public class Obj {
    public Timestamp aTimestamp;
}

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

xsi:type属性的原因是JAX-B喜欢生成可以反序列化的XML,因此需要指出它是什么类型,或者它只能将所有内容解析为字符串。您可以使用@XmlElementRef注释来创建模式替换组,从而消除此属性,但在这种情况下,将使用不同的元素名称生成XML。 E.g。

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

如果您在集合中有时间戳和字符串,则会生成以下XML结构。在这种情况下,xsi:type属性是不必要的,因为JAX-B可以从元素名称中知道要创建的类型。

<Obj>
    <timestamp>2009-02-14T00:31:30.001+01:00</timestamp>
    <string>test</string>
</Obj>

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

如果你只是一个简单的字符串集,你不关心反序列化回到具有正确类型的Java(或任何其他)对象,那么最简单的解决方案是让一个XmlAdapter只做适应完整Set<Object>Set<String>并自行处理转化。