I have a RESTful Jersey web service that returns objects as XML. One of the members of the returned object is one of several possible types (all derived from a common base class) which isn't known until runtime. I can't get this member to appear in the output XML, as I will show below.
I've reduced my problem to some sample classes:
@XmlRootElement
public abstract class Animal {
public String type;
public Animal() {
type = "?";
}
public Animal(String type) {
this.type = type;
}
}
@XmlRootElement
public class Mammal extends Animal {
public String name;
public Mammal() {
name = "?";
}
public Mammal(String type, String name) {
super(type);
this.name = name;
}
}
@XmlRootElement
public class Zoo {
private Animal creature;
@XmlElementRef
public Animal getCreature() {
return creature;
}
public void setCreature(Animal creature) {
this.creature = creature;
}
public Zoo() {
creature = new Mammal("Mouse", "Mickey");
}
}
@Path("/test")
public class TestResource {
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Zoo get() {
Zoo z = new Zoo();
return z;
}
}
When I call the service I get the following response:
<zoo/>
Which doesn't include the expected creature.
If I change the type of the member 'creature' from an Animal (abstract base class) to a Mammal (derived class) then I get the expected output, but that's not a suitable solution.
So I added the following code to the get() method:
// DIAGNOSTIC CODE: Convert object to XML and send to System.out
try {
JAXBContext context = JAXBContext.newInstance(Zoo.class, Mammal.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(z, System.out);
} catch (JAXBException ex) {
ex.printStackTrace();
}
and now even though the XML from the service is wrong (just the empty tag) I see the correct output in the console :
<?xml version="1.0" encoding="UTF-8"?>
<zoo>
<mammal>
<type>Mouse</type>
<name>Mickey</name>
</mammal>
</zoo>
Now, In order to get that output, I had to make sure that Mammal.class was passed to JAXBContext.newInstance(), otherwise I got the same empty tag in the output, so I'm guessing the problem is that the XML serialization being done by the web service doesn't know about the derived Mammal class, and thus can't serialize the object correctly. Is that a correct diagnosis? How do I fix it?