Spring MVC 可以有 HTTP PUT 方法的请求参数吗?还是必须使用 post?我应该使用哪个来实现 RESTful?

发布于 2024-12-17 20:50:41 字数 989 浏览 0 评论 0原文

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

I have a controller action I think should be an HTTP PUT, but Spring is complaining when I try and use @RequestParam in the controller action. Is request parameters not allowed for HTTP PUT methods, and is that why Spring is rejecting it?

@RequestMapping(value = "/{helpDocumentId}/vote", method = RequestMethod.PUT)
public void voteHelpfulness(@PathVariable long helpDocumentId, @RequestParam boolean isHelpful) {
    helpManager.voteOnHelpDocument(helpDocumentId, isHelpful);
}

When executed, it throws this error:

org.springframework.web.bind.MissingServletRequestParameterException: Required boolean parameter 'isHelpful' is not present

Of course, the isHelpful parameter IS present. I can make the above code work perfectly for HTTP POST, so I know this isn't the problem.

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

Is PUT the correct http method? This action modifies the helpDocument, but it doesn't create one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

赏烟花じ飞满天 2024-12-24 20:50:41

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,如 JQuery、Spring MVC @RequestBody 和 JSON - 使其协同工作,以免遇到415 不支持的媒体类型。

Since Spring 3.1, HttpPutFormContentFilter can be used to handle application/x-www-form-urlencoded data:

Filter that makes form encoded data available through the ServletRequest.getParameter*() family of methods during HTTP PUT requests.

The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT requests. This filter intercepts HTTP PUT requests where content type is 'application/x-www-form-urlencoded', reads form encoded content from the body of the request, and wraps the ServletRequest in order to make the form data available as request parameters just like it is for HTTP POST requests.

For other incoming data, such as JSON, you'll need @RequestBody as explained in JQuery, Spring MVC @RequestBody and JSON - making it work together, to not run into a 415 Unsupported Media Type.

呆° 2024-12-24 20:50:41

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

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

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

Spring controllers support GET/HEAD/POST/PUT/DELETE/OPTIONS/TRACE, but since your browser may not be able to send these request methods, it wont work for you.

The workaround is to use the "org.springframework.web.filter.HiddenHttpMethodFilter" provided by Spring. It requires you to pass a hidden parameter for the request method. The default parameter supported by this filter is "_method".

Check the javadoc of the filter for more info.

拒绝两难 2024-12-24 20:50:41

正如上面所建议的,这似乎是 spring/servlet API 中的一个错误。实际上,PUT 请求应该在请求正文(或有效负载) 上工作,而不是在请求参数上工作。从这个意义上说,servlet API 和 Servlet API 是一个很好的选择。 spring的处理是正确的。

话虽如此,更好、更简单的解决方法是不从 javascript/jQuery 调用中传递任何数据元素,并将参数作为 url 本身的一部分传递。也就是说,按照 GET 调用的方式在 url 字段中设置参数。

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

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

This, as suggest above, seems to be a bug in spring/servlet API. In reality PUT requests are supposed to work on Request Body (or payload) and not on Request Parameters. In that sense, servlet API & spring's handling is correct.

Having said that, a better and much easier workaround is to pass no data element from your javascript/jQuery call and pass your parameters as part of the url itself. meaning, set parameters in the url field the way you would do in a GET call.

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

now this works for simple parameters, i guess, will not work for complex JSON types. Hope this helps.

巷子口的你 2024-12-24 20:50:41

我按照评论中的建议将 @RequestParam 更改为 @RequestBody 并且它成功了(我的参数是一个字符串)。

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

I followed the recommendation in the comments and changed @RequestParam to @RequestBody and it just worked (my parameter is a String).

I agree this is a bug in Spring because the exact same code that fails in my production environment (when using @RequestParam) works fine in localhost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文