JAXB Can't Handle Interfaces in Generics
If you have a class with a List<Vehicle> and Vehicle is an interface, JAXB will throw an Exception at runtime:my.package.MyInterface is an interface, and JAXB can't handle interfaces
public abstract class Vehicle { public abstract String getType(); } @XmlRootElement public class Bus extends Vehicle { private String type; public Bus() { }; public Bus(String type) { this.type = type; } @XmlElement @Override public String getType() { return type; } public void setType(String type) { this.type = type; } } @XmlRootElement public class Car extends Vehicle { private String type; public Car() {}; public Car(String type) { this.type = type; } @XmlElement @Override public String getType() { return type; } public void setType(String type) { this.type = type; } } @XmlRootElement public class ObjectWithListOfVehicles { private List<Vehicle> list; @XmlElementWrapper(name="MyVehicleList") @XmlElement public List<Vehicle> getList() { return list; } public void setList(List<Vehicle> list) { this.list = list; } }
public static void interfaceExamples() throws JAXBException { List<Vehicle> l = new ArrayList<Vehicle>(); l.add(new Bus("Large bus")); l.add(new Bus("Small bus")); l.add(new Car("Ferrari")); // Object with generic list ObjectWithListOfVehicles owgl = new ObjectWithListOfVehicles(); owgl.setList(l); JAXBContext jc = JAXBContext.newInstance( Bus.class, Car.class, ObjectWithListOfVehicles.class); ObjectWithListOfVehicles retr = marshallUnmarshall(owgl, jc); for (Vehicle s : retr.getList()) { System.out.println( s.getClass().getSimpleName() + " - " + s.getType()); } System.out.println(" "); } public static <O> O marshallUnmarshall(O o, JAXBContext jc) throws JAXBException { // Creating a Marshaller Marshaller jaxbMarshaller = jc.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter result = new StringWriter(); jaxbMarshaller.marshal(o, result); // Printing XML String xml = result.toString(); System.out.println(xml); // Creating an Unmarshaller Unmarshaller jaxbUnmarshaller = jc.createUnmarshaller(); StringReader sr = new StringReader(xml); O retr = (O) jaxbUnmarshaller.unmarshal(sr); return retr; }
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <objectWithListOfVehicles> <MyVehicleList> <list xsi:type="bus" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <type>Large bus</type> </list> <list xsi:type="bus" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <type>Small bus</type> </list> <list xsi:type="car" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <type>Ferrari</type> </list> </MyVehicleList> </objectWithListOfVehicles> Bus - Large bus Bus - Small bus Car - Ferrari
Notice that JAXB is capable of recreating both Bus and Car instances.
Next
JAXB to XML • JAXB to JSON • JAXB Annotations Tutorial Table Of Content
Hi,
ReplyDeleteNice article. Here is an alternate approach that you can use with JAXB implementation when you are working with interfaces:
- JAXB and Interface Fronted Models
-Blaise
Hi,
ReplyDeleteReally very very nice article about JAXB...