【问题标题】:Unable to read application/json message in Response output无法读取响应输出中的应用程序/json 消息
【发布时间】:2015-09-28 12:52:50
【问题描述】:

我正在测试 REST API,当我进行 GET 调用以检索资源时,它会导致 500 Internal Server Error 并在输出中返回具有媒体类型 application/json 的消息:

[
  {
    "messageType": "Some error type",
    "messageText": "Some message text",
    "moreInfo": "Some info"
  }
]

请注意,在上面的输出中,Json 在 []

我想从上面的输出响应中读取messageText 的值。我试过 -

JsonObject jsonObject = response.readEntity(JsonObject.class);

但它会导致以下错误:

java.lang.IllegalStateException: Entity input stream has already been closed.
    at org.glassfish.jersey.message.internal.EntityInputStream.ensureNotClosed(EntityInputStream.java:225)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:830)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:783)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:399)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)

能否请您帮我如何阅读输出中的消息?我正在使用 Jersy 库。

【问题讨论】:

  • 您能否提供一些额外的代码。正如消息所暗示的那样,输入流似乎在之前的某个时间点已经关闭,并且无法再读取。
  • @peeskillet,我正在自动化这个测试而不是手动检查。我可以在 POSTMAN google chrome plugin for REST API testing 中手动查看。
  • 很难说没有可重现的东西。我会查看Jersey Test Framework。在处理泽西岛时,放置可重现的all into one class 是最好的MCVE。我强烈建议这样做以获得更好的帮助。您甚至可以在分解问题时自己找出问题。

标签: java json jersey jersey-client


【解决方案1】:

根据javaDoc,对 readEntity 的调用会关闭响应实体,因此当您再次调用 readEntity 时会收到 IllegalStateException。

除非提供的实体类型是输入流,否则此方法 自动关闭未使用的原始响应实体数据 如果打开则流式传输。

在我的例子中,有表达式response.readEntity(String.class) 当我在调试模式下运行代码时,在调试透视图的表达式窗格中导致此异常。表达式的计算消耗了实体并导致它关闭。

【讨论】:

  • 在这个问题上挠了挠头:D
  • 如果你想多次调用 readEntity(...) 可以使用 response.bufferEntity()
  • 我正在使用 bufferEntity() 但仍然面临这个问题。 stackoverflow.com/questions/45585665/…
  • 在 readEntity() 运行良好之前执行 response.bufferEntity()!
【解决方案2】:

我解决了这个问题,首先对 String 实体执行 readEntity,然后使用 Jackson ObjectMapper 实际反序列化到目标类。

有问题的代码:

Transactions transObj = response.readEntity(Transactions.class);

解决方案:

String stringEntity = response.readEntity(String.class);
Transactions transObj  = objectMapper.readValue(stringEntity, Transactions.class);

当响应实体流中的 JSON 字符串很长或很复杂可能需要在其上进行多次交互时,似乎会出现此问题。 “反序列化”为字符串似乎只需要咬一口。一旦您将字符串(以及 Jackson 或 GS​​ON)反序列化到目标实体,就会在不触及响应的情况下进行。

【讨论】:

    【解决方案3】:

    实际上,我们如何定义 Response 对象的引用是一个问题。 解决方法很奇怪

    不工作一个:

    Response response;
    if (condition) {
        response = 
    } else {
        response = 
    }
    String resp = response.readEntity(String.class);
        if (response.getStatus() == 200) {}
    

    一劳永逸

    Response response = null;
    if (condition) {
        response = 
    } else {
        response = 
    }
    String resp = response.readEntity(String.class);
    if (response.getStatus() == 200) {}
    

    所以基本上如果我们最初不为响应分配任何内容,Stream 将被关闭

    【讨论】:

      【解决方案4】:

      当您收到错误 500 时,您可能会在控制台/日志中看到另一个异常。您应该开始检查,然后尝试解决这个问题。如果您在日志中没有找到任何内容,能否请您发布更多代码?

      【讨论】:

      • 我正在自动化这个测试而不是手动检查。我可以在 POSTMAN 中手动看到这一点 - 用于 REST API 测试的谷歌浏览器插件。
      • 好的,抱歉我没听明白。实际上,正如您所说,问题可能是因为您收到的 JSON 不是实际的 JSON,因为它不是以 {.您使用的是哪个服务器?
      猜你喜欢
      • 2015-12-03
      • 1970-01-01
      • 2019-05-06
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2016-05-31
      相关资源
      最近更新 更多