Spring MVC可以为HTTP PUT方法提供请求参数,还是我必须使用post?我应该使用哪个RESTful?

时间:2011-11-23 23:21:49

标签: spring http rest spring-mvc http-put

我有一个控制器动作,我认为应该是一个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 个答案:

答案 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中工作正常。