我有一个以 XML 形式返回对象的 RESTful Jersey Web 服务。返回对象的成员之一是几种可能的类型之一(全部派生自一个公共基类),直到运行时才知道。我无法让该成员出现在输出 XML 中,如下所示。
我已将问题简化为一些示例类:
@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;
}
}
当我调用该服务时,我得到以下响应:
<zoo/>
其中不包括预期的生物。
如果我将成员“生物”的类型从动物(抽象基类)更改为哺乳动物(派生类),那么我会得到预期的输出,但这不是一个合适的解决方案。
所以我在 get() 方法中添加了以下代码:
// 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();
}
现在即使服务中的 XML 错误(只是空标签),我在控制台中看到了正确的输出:
<?xml version="1.0" encoding="UTF-8"?>
<zoo>
<mammal>
<type>Mouse</type>
<name>Mickey</name>
</mammal>
</zoo>
现在,为了获得该输出,我必须确保将 Mammal.class 传递给 JAXBContext.newInstance(),否则我在输出中得到相同的空标记,所以我猜问题是 XML 序列化由 Web 服务完成的操作不知道派生的 Mammal 类,因此无法正确序列化对象。这是一个正确的诊断吗?我如何解决它?