使用Jersey客户端读取实体时出现ClassCastException

时间:2017-05-12 08:26:20

标签: java xml jaxb jersey jax-rs

我有一个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
}

感谢您的任何见解。

0 个答案:

没有答案