【问题标题】:Read response body in JAX-RS client from a post request从发布请求中读取 JAX-RS 客户端中的响应正文
【发布时间】:2013-08-07 20:09:35
【问题描述】:

在移动应用程序和网络服务之间存在某种代理,我们对发出发布请求时的响应感到困惑。我们收到状态为 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.readEntity(String.class); 才能使其正常工作。非常感谢!

标签: java json web-services cxf jax-rs


【解决方案1】:

试试这个:

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

编辑

感谢@Martin Spamer 提到它仅适用于 Jersey 1.x jar。对于 Jersey 2.x 使用

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

【讨论】:

  • 这仅适用于来自 Jersey 的 Jax 1.x:2.x 及以上 OP 正在使用的版本(我们可以从他对 ClientBuilder.newClient(); 的使用中看出)。回复是response.readEntity(String.class);
  • 这不适用于 jaxrs-ri-2.16,在这里你会得到 org.glassfish.jersey.client.HttpUrlConnector$2@1255b1d1 作为输出。
  • 谢谢,当我使用 getEntity() 读取响应消息正文时,我被困了很长时间。 getEntity() 仅适用于 Jersey 1.x,而 Jersey 2.0 支持 response.readEntity() 以获取响应消息正文。
  • 请注意,如果您收到com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String,则需要手动读取响应流以获取 JSON 字符串。 Jersey 1.19 发生在我身上。
【解决方案2】:

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

String output = response.readEntity(String.class)

这会按预期交付内容。

【讨论】:

  • 球衣开发者让我发疯。每个版本的方法命名和/或整个工作流程都会发生巨大变化。这就像玩矿工游戏。从头开始查找所有地雷。
  • 你不喜欢敏捷吗? :)
  • @Whimusical 我认为他喜欢向后兼容 :)
【解决方案3】:

对于我的用例,之前的答案都不起作用,因为我正在编写一个服务器端单元测试,由于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();

【讨论】:

  • getEntity 不会自动读取任何支持的 InputStream,所以要小心。
【解决方案4】:

我也遇到了同样的问题,尝试运行使用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

希望这会有所帮助!

【讨论】:

  • 谢谢!您可能是第一个真正理解 OP 问题的人。对于所有其他急救人员:没有人关心你有多聪明。他们想解决他们的问题。他们对为什么 jersey 不允许您在单元测试中调用 readResponse 不感兴趣。
【解决方案5】:

根据文档,Jax rs 2.0 中的方法 getEntity 返回一个 InputStream。 如果需要将 InputStream 转换为 JSON 格式的 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.jersey 库的 jersey-client,第二个使用来自 org.glassfish.jersey.core 的 jersey-client。

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

我使用以下maven依赖:

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

我不知道为什么readEntity方法不起作用。希望您可以使用解决方案。

卡洛斯·塞佩达

【讨论】:

    【解决方案6】:

    实现代码的修改我找到了为什么阅读方法对我不起作用的原因。问题是我的项目使用 jersey 1.x 的依赖项之一。 更新版本,调整客户端,就可以了。

    我使用以下maven依赖:

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

    问候

    卡洛斯·塞佩达

    【讨论】:

      猜你喜欢
      • 2015-07-23
      • 2011-06-21
      • 2016-01-10
      • 2018-09-11
      • 2013-02-17
      • 2017-04-23
      • 2017-05-05
      • 2014-07-11
      • 1970-01-01
      相关资源
      最近更新 更多