Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法使用JSON实体测试Jax rs_Java_Junit_Jersey_Jax Rs_Resteasy - Fatal编程技术网

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

Java 无法使用JSON实体测试Jax rs,java,junit,jersey,jax-rs,resteasy,Java,Junit,Jersey,Jax Rs,Resteasy,我正试图通过以下方式测试Jax rs资源, 我正在使用容器jersey测试框架提供程序jdkhttp 我可以断言状态代码。但是,当我尝试读取实体时,会出现异常: 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.inter

我正试图通过以下方式测试Jax rs资源,
我正在使用容器
jersey测试框架提供程序jdkhttp

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

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

有人能帮忙吗?

因为例外情况是您缺少内容类型为
application/json
的MessageBodyReader。你的类路径上有JacksonJsonProvider吗?它可以作为依赖项添加到jackson jaxrs json提供程序中:

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

例外情况是,您缺少内容类型为
application/json
的MessageBodyReader。你的类路径上有JacksonJsonProvider吗?它可以作为依赖项添加到jackson jaxrs json提供程序中:

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

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

我怀疑您测试中的json解析器被大括号误导了。基本上,它认为您返回的是json对象,而不是json字符串。尝试返回
“Status:OK”

问题源于类路径上同时有Jersey和RestEasy客户端。在
JerseyTest
上调用
target()
时,将从通过调用
ClientBuilder.newClient()
构建的
客户端获取
WebTarget

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

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

因此,即使您正在使用Jersey的测试框架,所使用的
客户机
也是RESTeasy的实现。我猜所有带有实体提供者的标准配置都不会被配置。字符串和application/json之间的转换是您案例中需要的标准提供程序之一

我想说的是,只需显式地使用Jersey客户端实现。您将无法在
运动衫测试中调用
目标
。您需要显式地创建客户机

@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

注意,我说过标准提供者支持
字符串
应用程序/json
。因此,如果您将只序列化字符串,那么您不需要其他任何东西。如果希望Jersey客户端(和服务器端)支持POJO序列化,则应添加以下内容

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

org.glassfish.jersey.media
泽西媒体公司
${jersey2.version}
测验

问题源于类路径上同时有Jersey和RestEasy客户端。在
JerseyTest
上调用
target()
时,将从通过调用
ClientBuilder.newClient()
构建的
客户端获取
WebTarget

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

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

因此,即使您正在使用Jersey的测试框架,所使用的
客户机
也是RESTeasy的实现。我猜所有带有实体提供者的标准配置都不会被配置。字符串和application/json之间的转换是您案例中需要的标准提供程序之一

我想说的是,只需显式地使用Jersey客户端实现。您将无法在
运动衫测试中调用
目标
。您需要显式地创建客户机

@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

注意,我说过标准提供者支持
字符串
应用程序/json
。因此,如果您将只序列化字符串,那么您不需要其他任何东西。如果希望Jersey客户端(和服务器端)支持POJO序列化,则应添加以下内容

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

org.glassfish.jersey.media
泽西媒体公司
${jersey2.version}
测验