Jaxb and abstract classes

I try to use JAXB to unmarshall some XML, but I get the exception "Unable to instantiate ...". I understand why - he is trying to instantiate an abstract class. I want it to instantiate a specific implementation class. My goal is to have special checks on setter methods. Perhaps "qux" is the actual baz value for BarImpl, but BarImpl2 wants to do something else.

I got part of this path without commenting on Foo, but if I turn off the bar, everything will become ugly.

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 = "<foo>" + " <bar>" + " <baz>qux</baz>" + " </bar>" + "</foo>"; 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 { } } 
+7
source share
1 answer

You can do the following:

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 = "<foo>" + " <bar>" + " <baz>qux</baz>" + " </bar>" + "</foo>"; 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 { } } 
+14
source

All Articles