【问题标题】:Possible to have Spring @RequestBody and HttpEntity at the same time?可以同时拥有 Spring @RequestBody 和 HttpEntity 吗?
【发布时间】:2018-06-17 04:06:17
【问题描述】:

我的 Spring Boot 应用程序中有以下代码:

@RestController
@RequestMapping("/execute")
public class RestCommandExecutor {

  @PostMapping
  public Response executeCommand(@RequestBody Command command, 
                                 HttpEntity<String> httpEntity) {
    System.out.println(command);
    System.out.println("********* payload is: " + httpEntity.getBody());

    return new Response("Hello text", new Long(123));
  }
}

当 POST 请求带有正确的 Command 时,我收到 I/O 错误:

.w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed

我希望 Spring 将请求正文转换为 Command,但由于 JSON 包含的内容超过了 Command 类的一部分,因此我也希望获得完整的原始 JSON。

有没有办法通过方法中的映射来实现呢?我知道我总是可以这样做public Response executeCommand(HttpEntity&lt;String&gt; httpEntity),然后使用 Jackson 手动将其转换为 Command,但我宁愿不必手动这样做。

这可能吗?

【问题讨论】:

  • 为什么要转成Command?
  • 检索其type 属性。然后,我会将其反序列化为可以转换所有命令属性的类型。

标签: java spring spring-restcontroller spring-boot-actuator


【解决方案1】:

您不能同时读取HttpEntity 的正文和使用@RequestBody 的原因是两者都从HttpRequestInputStream 读取并在之后关闭它。由于InputStream 关闭后您无法再次读取它,因此如您所见,最后一次操作失败。

看来您真正想要的是访问一些未映射到 Command 类中的属性,尤其是使用 type 属性指定的类。 您可以使用 Jackson 的 @JsonTypeInfo@JsonSubtype 注释来做到这一点,它们允许您自定义类层次结构的反序列化。

【讨论】:

  • 感谢您的解释。这确实有道理。我不能使用你的建议,因为我不知道(预先)会出现什么类型,但尽管如此。
猜你喜欢
  • 2011-03-07
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2018-01-31
相关资源
最近更新 更多