JAXB编组声明父类与实际运行时子类

时间:2010-07-01 05:10:19

标签: java jaxb subclass

我正在使用JAXB编组一个具有声明为类Foo的实例变量的类。在运行时,实例变量被设置为Foo的子类的实例,让我们说FooBar。类Foo和FooBar上都有基本的JAXB注释。

XML输出显示正在封送Foo的实例而不是FooBar。是否有一些特定的注释要告诉JAXB如何正确编组运行时子类来代替声明的超类?

我尝试了一个实验,其中我直接编组了一个Foo类型的实例变量foo,它在运行时被设置为FooBar的一个实例。它正确编组了一个FooBar实例。

这明显不同于编组包含Foo类型的实例变量的类,因为marshal调用是在包含类上进行的,而JAXB只是编组该类字段(我正在使用@XmlAccessorType(XmlAccessType.FIELD)注释)。

我的期望是JAXB可以正确检查实例变量的运行时类型,但可能并非如此。这种情况是否需要使用此处所述的XmlAdapter实现?

JAXB inheritance, unmarshal to subclass of marshaled class

谢谢,

克里斯

1 个答案:

答案 0 :(得分:7)

我将以这些类为例:

@XmlRootElement
class Foo { public Bar bar; }
class Bar {}
class Baz extends Bar {}
class Quux extends Bar {}

嗯,似乎有两种可能的解决方案:

您可以在创建上下文时告诉JAXB所有涉及的类(包括子类)。

JAXBContext.newInstance(Foo.class, Bar.class, Baz.class, Quux.class);

通过@XmlSeeAlso注释告诉JAXB其他类。

@XmlRootElement
@XmlSeeAlso({Baz.class, Quux.class})
class Foo { public Bar bar; }

如果你像这样编组

Foo f = new Foo();
f.bar = new Baz();

m.marshal(f, System.err);

你收到了

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
    <bar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="baz"/>
</foo>

它不漂亮,但保留了类型信息。