从post请求中读取JAX-RS客户端中的响应主体



在移动应用程序和web服务之间有某种代理,我们对发布请求时的响应感到困惑。我们收到状态为200的响应:OK。但我们找不到/提取JSON响应体。

    Client client = ClientBuilder.newClient();
    WebTarget webTarget = client.target(WEBSERVICE_BASE_LOCATION + "mobileDevices?operatorCode=KPNSCP");
    String jsonString = "{"osVersion":"4.1","apiLevel":16,"devicePlatform":"ANDROID"}";
    Builder builder = webTarget.request();
    Response response = builder.post(Entity.json(jsonString));

我们正在使用JAX-RS。有人能提供一些提示从服务器响应中提取JSON主体(String)吗?

试试这个:

String output = response.getEntity(String.class);

编辑

感谢@martinSpamer提到它只适用于Jersey 1.x罐子。对于Jersey 2.x,请使用

String output = response.readEntity(String.class);

我刚刚找到了jaxrs-ri-2.16的解决方案-只需使用

String output = response.readEntity(String.class)

这将按预期交付内容。

对于我的用例,之前的答案都不起作用,因为我正在编写一个服务器端单元测试,该测试由于以下错误消息而失败,如Unable to Mock Glassfish Jersey Client Response Object问题中所述:

java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)
at ...

此异常发生在以下代码行:

String actJsonBody = actResponse.readEntity(String.class);

修复方法是将问题代码行转换为:

String actJsonBody = (String) actResponse.getEntity();

我也遇到了同样的问题,试图运行一个使用readEntity的单元测试调用代码。不能在生产代码中使用getEntity,因为它只返回ByteInputStream,而不是正文的内容,而且我不可能添加只在单元测试中命中的生产代码。

我的解决方案是创建一个响应,然后使用Mockito间谍来模拟readEntity方法:

Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);

请注意,不能使用when(mockResponse.readEntity(String.class)选项,因为它会抛出相同的IllegalStateException

希望这能有所帮助!

Kotlin

使用Kotlin 的相同版本的答案

(response.entity as InputStream).bufferedReader().use { it.readText() }
根据文档,Jax rs 2.0中的getEntity方法返回一个InputStream。如果需要使用JSON格式将InputStream转换为String,则需要强制转换这两种格式。例如,在我的案例中,我实现了下一个方法:
    private String processResponse(Response response) {
    if (response.getEntity() != null) {
        try {
            InputStream salida = (InputStream) response.getEntity();
            StringWriter writer = new StringWriter();
            IOUtils.copy(salida, writer, "UTF-8");
            return writer.toString();
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }
    return null;
}

为什么我实现了这个方法。因为在不同的博客中读到,许多开发人员在jaxrs中使用下一种方法的版本时都有相同的问题

String output = response.readEntity(String.class)

String output = response.getEntity(String.class)

第一个使用com.sun.jsey库中的jersey客户端工作,第二个使用org.lassfish.jersey.core.中的jessey客户端工作

这是呈现给我的错误:org.glassfish.jersy.client.internal.HttpUrlConnector$2不能转换为java.lang.String

我使用以下maven依赖项:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

我不知道的是为什么readEntity方法不起作用。我希望你能使用这个解决方案。

Carlos Cepeda

意识到对代码的修订,我发现了读取方法不适用于我的原因。问题是我的项目使用的依赖项之一是jersey 1.x。更新版本,调整客户端,它就工作了。

我使用以下maven依赖项:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

问候

Carlos Cepeda

最新更新