我有一个JAX-RS资源,它返回A
类型的对象。我使用JAXB序列化为XML。服务器工作正常,我能够将正确的XML检索为字符串。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><a><x>xA</x>/a>
问题显示我使用Jersey测试客户端读取服务器生成的对象。实际上,为了反序列化XML,我使用了用于序列化的原始类B
的子类A
,它具有额外的setter(能够捕获这些属性)。但是,我收到java.lang.ClassCastException
的消息,其中包含test.AppTest$A cannot be cast to test.AppTest$B
。
我的问题是,即使没有序列化类型信息,Jersey客户端或JAXB如何知道服务器端的序列化对象的类型(即A
)?
我的理解是JAX-RS实现(在本例中为Jersey)将尝试使用B
对XML内容进行反序列化,并且对于用于序列化的类型是不可知的。这似乎并非如此。
这是一个极少运作的例子。
package test;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Path("/")
public class AppTest extends JerseyTest {
public AppTest() {
}
@Override
protected Application configure() {
return new ResourceConfig(AppTest.class);
}
@GET
@Consumes(MediaType.APPLICATION_XML)
public A get() {
return new A();
}
@Test
public void testApp() {
B b = this.target().request()
.accept(MediaType.APPLICATION_XML_TYPE)
.get().readEntity(B.class);
}
@XmlRootElement
public static class A {
public A() {}
@XmlElement
public String getX() { return "xA";}
}
@XmlRootElement
public static class B extends A {
public B() {}
public void setX(String value) {}
}
}
除了JUnit 4.12之外,该示例仅直接依赖于以下工件:org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:2.25.1
。我尝试了不同的口味(在记忆中,码头)同样的观察。
如果我将b
检索为Object
,则表示正常,但b
的类型为A
。
@Test
public void testApp() {
Object b = this.target().request()
.accept(MediaType.APPLICATION_XML_TYPE)
.get().readEntity(B.class);
System.out.println(b.getClass()); # class test.AppTest$A
}
感谢您的任何见解。