在DELETE请求的正文中传递数据

Ale*_*lex 24 spring spring-mvc

我有两个Spring MVC控制器方法.两者都接收请求体中相同的数据(在HTLM的格式POST形式:version=3&name=product1&id=2),但一个方法处理PUT请求和另一DELETE:

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.PUT)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.DELETE)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}
Run Code Online (Sandbox Code Playgroud)

在第一种方法中,product参数的所有字段都已正确初始化.在第二个中,仅id初始化字段.其他字段是null或0.(id可能是因为id路径变量而初始化).

我可以看到该HttpServletRequest对象包含请求体(version=3&name=product1&id=2)中所有字段的值.它们只是没有映射到product参数的字段.

如何使第二种方法有效?

我也尝试使用带@RequestParam注释的参数.在处理PUT请求的方法中,它可以工作.在DELETE方法中,我得到一个例外:org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'version' is not present.

我需要在DELETE请求体中传递数据,因为数据包含用于乐观锁定的行版本.

geo*_*and 33

问题不是Spring问题,而是Tomcat问题.

默认情况下,当HTTP方法为POST(至少对于我检查过的版本7.0.54但是对于所有Tomcat 7版本可能相同)时,Tomcat将仅解析表单样式中的参数.

为了能够处理DELETE方法,您还需要设置parseBodyMethodsTomcat连接器的属性.连接器配置完成server.xml.

您更新的连接器很可能如下所示:

<Connector port="8080" protocol="HTTP/1.1" 
           connectionTimeout="20000"
           redirectPort="8443"
           parseBodyMethods="POST,PUT,DELETE"
           URIEncoding="UTF-8" />
Run Code Online (Sandbox Code Playgroud)

以下是配置Tomcat连接器的文档页面.

一旦你设置Tomcat来解析参数,Spring就可以正常工作(尽管在你的情况下你可能需要@RequestBody从控制器方法中删除)