【问题标题】:Spring MVC controller with multiple @RequestBody具有多个 @RequestBody 的 Spring MVC 控制器
【发布时间】:2013-09-09 02:28:07
【问题描述】:

我想知道例如 SpringMVC 控制器是否可以具有方法签名,例如

@RequestMapping(value = "/target", method = RequestMethod.POST)
@ResponseBody
public void acceptObject(@RequestBody MyObjectDto dto,@RequestBody String messageBody) {
    //Authenticate messageBody
    //Process mapped DTO
}

目的是将 JSON 发布到此控制器,原始消息正文将进行完整性身份验证,如果正确,JSON 将映射到可以移交处理的 DTO。

目前我结束了

java.io.IOException: Stream closed

【问题讨论】:

  • 你解决了这个问题了吗?我遇到了同样的问题,正在考虑打开另一个线程,因为下面的答案并不是我真正想要的。
  • 答案可以总结为“否”,所以一般的解决方案是简单地接受消息体作为字符串,验证其完整性,然后使用 Jackson 手动将此字符串映射到对象。跨度>

标签: spring spring-mvc


【解决方案1】:

Spring 使用一个名为HandlerMethodArgumentResolver 的接口来决定它将哪些参数传递给您的处理程序方法。对于带有@RequestBody 注释的参数,它使用一个名为RequestResponseBodyMethodProcessor 的类。此类基本上在一组HttpMessageConverter 对象中查找可以读取请求的content-type 并可以转换为指定类型的对象。如果找到,它将HttpServletRequest 的主体作为InputStream 传递给HttpMessageConverter 对象。

在这种情况下,您可能会发现一些 JSON 反序列化器正在工作。它很可能(看到你得到的IOException)消耗流然后关闭它。

所以实际上这种做事方式是不可能直接实现的。

一种解决方案是创建一个Filter,在您自己的实现中包装HttpServletRequest,缓冲InputStream,使其可根据需要多次重复使用/读取。但是,从主体反序列化的规则可能由 Spring 假定,而不是您想要的。在这种情况下,您可以创建自己的AnnotationHandlerMethodArgumentResolver,然后在您的配置中注册应用程序。然后,您可以准确控制从请求正文中反序列化的方式。

另一个解决方案是将 MyObjectDtomessageBody 合并到一个 DTO 中,如果这对您的数据模型(以及 Spring 反序列化过程)有意义的话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 2012-10-05
    • 2011-08-26
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多