20

我有一个控制器操作,我认为应该是 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,但不会创建一个。

4

4 回答 4

15

Spring 3.1 开始,可以使用HttpPutFormContentFilterapplication/x-www-form-urlencoded来处理数据:

ServletRequest.getParameter*()在 HTTP PUT 请求期间通过一系列方法使表单编码数据可用的过滤器。

Servlet 规范要求表单数据可用于 HTTP POST,但不能用于 HTTP PUT 请求。此过滤器拦截内容类型为 的 HTTP PUT 请求,'application/x-www-form-urlencoded'从请求正文中读取表单编码的内容,并包装 ServletRequest 以使表单数据可用作请求参数,就像它用于 HTTP POST 请求一样。

对于其他传入数据,例如 JSON,您需要@RequestBody按照JQuery、Spring MVC @RequestBody 和 JSON 中的说明 - 使其协同工作,以免遇到 415 Unsupported Media Type。

于 2013-01-28T18:41:48.077 回答
6

Spring 控制器支持 GET/HEAD/POST/PUT/DELETE/OPTIONS/TRACE,但由于您的浏览器可能无法发送这些请求方法,因此对您不起作用。

解决方法是使用Spring提供的“org.springframework.web.filter.HiddenHttpMethodFilter” 。它要求您为请求方法传递一个隐藏参数。此过滤器支持的默认参数是“_method”。

检查过滤器的 javadoc 以获取更多信息。

于 2011-12-05T12:00:19.470 回答
3

如上所述,这似乎是spring/servlet API. 实际上PUT,请求应该在请求参数上Request Body (or payload)而不是在请求参数上工作。从这个意义上说,servlet API & spring 的处理是正确的。

话虽如此,一个更好、更简单的解决方法是不从您的javascript/jQuery调用中传递任何数据元素,并将您的参数作为 url 本身的一部分传递。意思是,在 url 字段中设置参数,就像您在GET调用中所做的那样。

$.ajax({
            url: "/help/" + helpDocumentId + "/vote.json" + "?param1=param2Val&..",
            type: "PUT",
            data: "",
            success: function(response) {
                // ....
            }
     });

现在这适用于简单的参数,我猜,不适用于复杂的 JSON 类型。希望这可以帮助。

于 2012-01-20T11:22:43.847 回答
0

我按照评论中的建议更改@RequestParam@RequestBody并且它刚刚工作(我的参数是一个字符串)。

我同意这是 Spring 中的一个错误,因为在我的生产环境中失败的完全相同的代码(使用时@RequestParam)在 localhost 中运行良好。

于 2015-01-26T18:04:13.753 回答