【问题标题】:Unable to test Jax-rs with JSON entity无法使用 JSON 实体测试 Jax-rs
【发布时间】:2016-04-01 05:24:08
【问题描述】:

我正在尝试通过关注 https://jersey.java.net/documentation/latest/test-framework.html 来测试 Jax-rs 资源,
我正在使用容器jersey-test-framework-provider-jdk-http

我可以断言状态码。但是,当我尝试读取实体时,出现异常:

javax.ws.rs.ProcessingException: Unable to find a MessageBodyReader of content-type application/json and type class java.lang.String
    at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:39)
    at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:73)
    at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:50)
    at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:248)
    at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:181)
    at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:217)

我的资源类:

@Path("/")
public class SampleResource {
    @GET
    @Path("/health")
    @Produces(MediaType.APPLICATION_JSON)
    public String getServiceStatus() {
        return "{\"Status\": \"OK\"}";
    }    
}

我的测试班:

public class TestSampleResource extends JerseyTest {
    @Override
    protected Application configure() {
        return new ResourceConfig(SampleResource.class);
    }

    @Test
    public void testHealthEndpoint() {            
        Response healthResponse = target("health").request(MediaType.APPLICATION_JSON).get();

        Assert.assertEquals(200, healthResponse.getstatus());  // works

        String body = healthResponse.readEntity(String.class);
        Assert.assertEquals("{\"Status\": \"OK\"}", body);
    }        
}

有人可以帮忙吗?

【问题讨论】:

    标签: java junit jersey jax-rs resteasy


    【解决方案1】:

    问题来自于在类路径上同时拥有 Jersey 和 RestEasy 客户端。当您在JerseyTest 上调用target() 时,WebTarget 是从通过调用ClientBuilder.newClient() 构建的Client 获得的。

    ClientBuilder是一个标准的JAX-RS API,首先实现是通过META-INF/services文件搜索ClientBuilder的实现,寻找一个名为javax.ws.rs.client.ClientBuilder的文件,其内容为名称ClientBuilder 的实现。如果没有找到这样的文件,则默认寻找JerseyClientBuilder。

    jersey-client 没有这样的文件 META-INF/services/javax.ws.rs.core.ClientBuilder 因为它的 ClientBuilder 是 JAX-RS 客户端的默认值。如果你查看你的resteasy-client jar,你会看到它确实有那个文件。如果您查看该文件的内容,您将看到 ResteasyClientBuilder 作为实现。

    因此,即使您使用的是 Jersey 的测试框架,所使用的 Client 也是 RESTeasy 的实现。而且我猜实体提供者的所有标准配置都不会被配置。 String 和 application/json 之间的转换是您需要的标准提供程序之一。

    我会说只是明确地使用 Jersey 客户端实现。您将无法再通过JerseyTest 拨打target。您将需要显式创建客户端

    @Test
    public void dotest() {
        final Client client = new JerseyClientBuilder().build();
        WebTarget target = client.target("http://localhost:9998");
        final Response response = target.path("health").request().get();
        final String json = response.readEntity(String.class);
    }
    

    JerseyTest 的默认基本路径是 http://localhost:9998,所以我明确地创建了 WebTarget。

    请注意,我说String 到/来自application/json 是由标准提供商支持的。因此,如果您只序列化字符串,那么您不需要其他任何东西。如果你想要 Jersey 客户端(和服务器端)的 POJO 序列化支持,你应该添加以下内容

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>${jersey2.version}</version>
        <scope>test</scope>
    </dependency>
    

    【讨论】:

      【解决方案2】:

      我怀疑你的测试中的 json 解析器被花括号的存在误导了。基本上它认为你正在返回一个 json 对象,而不是一个 json 字符串。尝试返回"Status:OK"

      【讨论】:

        【解决方案3】:

        正如异常所说,您缺少内容类型 application/json 的 MessageBodyReader。你的类路径上有 JacksonJsonProvider 吗?它可以作为依赖添加到jackson-jaxrs-json-provider:

        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>2.7.3</version>
        </dependency>
        

        然后在你的测试应用中注册 JacksonJsonProvider:

        @Override
        protected Application configure() {
            return new ResourceConfig(SampleResource.class, JacksonJsonProvider.class);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-10
          • 2012-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多