我有一个控制器动作,我认为应该是一个HTTP PUT,但是当我尝试在控制器动作中使用@RequestParam时,Spring正在抱怨。 HTTP PUT方法不允许使用请求参数,这就是Spring拒绝它的原因吗?
@RequestMapping(value = "/{helpDocumentId}/vote", method = RequestMethod.PUT)
public void voteHelpfulness(@PathVariable long helpDocumentId, @RequestParam boolean isHelpful) {
helpManager.voteOnHelpDocument(helpDocumentId, isHelpful);
}
执行时会抛出此错误:
org.springframework.web.bind.MissingServletRequestParameterException: Required boolean parameter 'isHelpful' is not present
当然,isHelpful
参数存在。我可以使上面的代码完美地用于HTTP POST,所以我知道这不是问题。
$.ajax({
url: "/help/" + helpDocumentId + "/vote.json",
type: "PUT",
data: {
isHelpful: isHelpful
},
success: function(response) {
// ....
}
});
PUT是否正确的http方法?此操作会修改helpDocument
,但不会创建一个。
答案 0 :(得分:15)
Since Spring 3.1,HttpPutFormContentFilter可用于处理application/x-www-form-urlencoded
数据:
在HTTP PUT请求期间通过
ServletRequest.getParameter*()
系列方法使表单编码数据可用的过滤器。Servlet规范要求表单数据可用于HTTP POST,但不能用于HTTP PUT请求。此过滤器拦截内容类型为
'application/x-www-form-urlencoded'
的HTTP PUT请求,从请求正文中读取编码内容,并包装ServletRequest以使表单数据可用作请求参数,就像HTTP POST请求一样
对于其他传入数据(例如JSON),您需要@RequestBody
中所述的{{1}},以免遇到415不支持的媒体类型。
答案 1 :(得分:6)
Spring控制器支持GET / HEAD / POST / PUT / DELETE / OPTIONS / TRACE,但由于您的浏览器可能无法发送这些请求方法,因此它不适合您。
解决方法是使用Spring提供的“org.springframework.web.filter.HiddenHttpMethodFilter”。它要求您为请求方法传递隐藏参数。此过滤器支持的默认参数是“_method”。
检查过滤器的javadoc以获取更多信息。
答案 2 :(得分:3)
如上所述,这似乎是spring/servlet API
中的错误。实际上,PUT
请求应该在Request Body (or payload)
上工作,而不是在请求参数上。从这个意义上讲,servlet API&春天的处理是正确的。
话虽如此,更好,更简单的解决方法是从javascript/jQuery
调用中传递数据元素,并将您的参数作为网址本身的一部分传递。意思是,在网址字段中设置参数,就像在GET
调用中一样。
$.ajax({
url: "/help/" + helpDocumentId + "/vote.json" + "?param1=param2Val&..",
type: "PUT",
data: "",
success: function(response) {
// ....
}
});
现在这适用于简单的参数,我猜,它不适用于复杂的JSON类型。希望这可以帮助。
答案 3 :(得分:0)
我按照评论中的建议进行了操作,并将@RequestParam
更改为@RequestBody
并且它刚刚起作用(我的参数是字符串)。
我同意这是Spring中的一个错误,因为在我的生产环境中失败的完全相同的代码(使用@RequestParam
时)在localhost中工作正常。