无法使用JSON实体测试Jax-rs

时间:2016-04-01 05:24:08

标签: java junit jersey jax-rs resteasy

我正在尝试通过遵循此https://jersey.java.net/documentation/latest/test-framework.html来测试Jax-rs资源 我正在使用容器<div class="row"> <div class="medium-8 columns"> <p> <img src="http://www.bandwagonbible.com/Stories/Lifestyle/AprilFoolsPrank/Main.jpg"> </p> </div> <div class="medium-4 columns"> <p> <img src="http://www.bandwagonbible.com/Stories/LifeHacks/GetRich/Image4.jpg" alt="advertisement for deep fried Twinkies" class="nostyle"> </p> <p> <img src="http://www.bandwagonbible.com/Stories/Fitness/GettingSixPackAbs/Image2.jpg" alt="article promo image" class="nostyle"> </p> </div> </div>

我可以断言状态代码。但是,当我尝试readEntity时,我得到了异常:

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\"}";
    }    
}

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:5)

问题来自于在类路径上同时使用Jersey和RestEasy客户端。当您在target()上致电JerseyTest时,WebTarget是通过致电ClientClientBuilder.newClient()获得的。

ClientBuilder是标准的JAX-RS API,首先实现它通过ClientBuilder文件搜索META-INF/services的实现,查找名为{{1的文件},其内容是javax.ws.rs.client.ClientBuilder的实现名称。如果找不到此类文件,则默认为查找ClientBuilder

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

因此,即使您使用的是Jersey测试框架,正在使用的ResteasyClientBuilder也是RESTeasy的实现。我想所有与实体提供商的标准配置永远不会配置。 String和application / json之间的转换是您需要的标准提供者之一。

我想说明确使用Jersey客户端实现。您将无法再在Client上致电target。您需要明确创建客户端

JerseyTest

@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。因此,如果您只是序列化字符串,那么您不需要任何其他内容。如果您想为Jersey客户端(和服务器端)提供POJO序列化支持,则应添加以下内容

application/json

答案 1 :(得分:0)

正如异常所说,您缺少内容类型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);
}

答案 2 :(得分:0)

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