JAXB和抽象类

我正在尝试使用JAXB解组一些XML,但我得到了“无法创建…的实例”exception。 我理解为什么 – 它试图创建一个抽象类的实例。 我想要的是让它成为特定实现类的实例。 我的目标是对setter方法进行特定于类的检查。 也许“qux”是BarImpl的有效baz值,但BarImpl2想要做其他事情。

通过不注释Foo,我在那里得到了一部分,但如果我不注意酒吧,那么事情会变得难看。

import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.junit.Test; public class JAXBTest { @Test public void test() throws javax.xml.bind.JAXBException { String xml = "" + " " + " qux" + " " + ""; javax.xml.bind.JAXBContext context = javax.xml.bind.JAXBContext.newInstance( FooImpl.class, BarImpl.class ); javax.xml.bind.Unmarshaller unmarshaller = context.createUnmarshaller(); unmarshaller.unmarshal(new java.io.StringReader(xml)); } @XmlRootElement(name="foo") public static abstract class Foo { @XmlElement(name="bar") Bar bar; } @XmlRootElement(name="bar") public static abstract class Bar { @XmlElement(name="baz") String baz; } public static class FooImpl extends Foo { } public static class BarImpl extends Bar { } } 

您可以执行以下操作:

  • 使用@XmlRootElement而不是抽象类注释impl类。
  • 使用@XmlTransient标记抽象类(请参阅http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html )
  • bar属性上使用@XmlElement(type=BarImpl.class)来指定具体类型(请参阅http://blog.bdoughan.com/2011/05/jaxb-and-interface-fronted-models.html )。

JAXBTest

 import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import org.junit.Test; public class JAXBTest { @Test public void test() throws javax.xml.bind.JAXBException { String xml = "" + " " + " qux" + " " + ""; javax.xml.bind.JAXBContext context = javax.xml.bind.JAXBContext.newInstance( FooImpl.class, BarImpl.class ); javax.xml.bind.Unmarshaller unmarshaller = context.createUnmarshaller(); unmarshaller.unmarshal(new java.io.StringReader(xml)); } @XmlTransient public static abstract class Foo { @XmlElements({ @XmlElement(name="bar",type=BarImpl.class), @XmlElement(name="bar",type=BarImpl2.class), }) Bar bar; } @XmlTransient public static abstract class Bar { @XmlElement(name="baz") String baz; } @XmlRootElement(name="foo") public static class FooImpl extends Foo { } @XmlRootElement(name="bar") public static class BarImpl extends Bar { } public static class BarImpl2 extends Bar { } }