具有多个@RequestBody的Spring MVC控制器

时间:2013-09-09 02:28:07

标签: spring spring-mvc

我想知道例如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

1 个答案:

答案 0 :(得分:13)

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

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

所以这种做事的方式并不是直接可行的。

一种解决方案是在您自己的实现中创建一个Filter来缓存HttpServletRequest,以使其可重复使用/重新读取所需的次数。但是,从身体反序列化的规则可能会被Spring假设,而不是你想要的。在这种情况下,您可以创建自己的InputStreamAnnotation,然后在配置中注册应用程序。然后,您可以从请求正文中精确控制事件的反序列​​化。

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