无法使用JSON实体测试Jax-rs [英] Unable to test Jax-rs with JSON entity

查看:105
本文介绍了无法使用JSON实体测试Jax-rs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to test a Jax-rs resource by following this https://jersey.java.net/documentation/latest/test-framework.html,
and I am using container jersey-test-framework-provider-jdk-http

我可以声明状态码.但是,当我尝试读取实体时,出现异常:

I can assert status code. However, when I try to readEntity, I get exception:

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);
    }        
}

任何人都可以帮忙吗?

推荐答案

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

The problem comes from having both Jersey and RestEasy client on the classpath. When you call target() on the JerseyTest, the WebTarget is obtained from a Client that is built by calling ClientBuilder.newClient().

The ClientBuilder is a standard JAX-RS API, and it is implemented first to search for an implementation of ClientBuilder through the META-INF/services files, looking for a file named javax.ws.rs.client.ClientBuilder, whose content is the name of an implementation of the ClientBuilder. If no such file is found, it defaults to looking for JerseyClientBuilder.

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

jersey-client has no such file META-INF/services/javax.ws.rs.core.ClientBuilder because it's ClientBuilder is the default for JAX-RS client. If you look in your resteasy-client jar, you will see the it does have that file. And if you look in the contents of that file, you will see the ResteasyClientBuilder as the implementation.

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

So even though you are using Jersey's test framework, the Client being used, is RESTeasy's implementation. And I guess all the standard configurations with entity providers never gets configured. Conversion between String and application/json is one of those standard providers you need in your case.

我想说的是明确使用Jersey客户端实现.您将不再能够在JerseyTest上呼叫target.您将需要显式创建客户端

I would say just explicitly use Jersey client implementation. You will no longer be able to call target on the JerseyTest. You will need to explicitly create the client

@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.

The default base path for JerseyTest is http://localhost:9998, so I explicitly create the WebTarget with that.

请注意,我说过Stringapplication/json或从application/jsonapplication/json受标准提供程序支持.因此,如果您仅要序列化字符串,则不需要任何其他操作.如果要对Jersey客户端(和服务器端)进行POJO序列化支持,则应添加以下内容

Note that I said the String to/from application/json is supported by standard providers. So if you will only be serializing Strings, then you don't need anything else. If you want POJO serialization support for the Jersey client (and server side), you should add the following

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

这篇关于无法使用JSON实体测试Jax-rs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆