如果使用 PUT,SpringMVC 无法识别请求主体参数

发布于 2024-11-05 01:49:22 字数 878 浏览 1 评论 0 原文

也许这应该行不通,但至少我想明白为什么。我在 PUT 主体中传递了一个简单的 val=somevalue 但 spring 发回了一个 400 Bad Request 因为它似乎无法识别 val 参数。

类似的请求适用于 POST。 SpringMVC 是否无法将 PUT 请求主体识别为参数源?

在这两种情况下,Content=-Type 均正确设置为 application/x-www-form-urlencoded。

spring拒绝调用的方法是这样的:

@RequestMapping(value = "config/{key}", method = RequestMethod.PUT)
@ResponseBody
public void configUpdateCreate(final Model model, @PathVariable final String key, @RequestParam final String val,
        final HttpServletResponse response) throws IOException
{
    //...
}

为了完整起见,这里是jquery ajax调用。我看不出这有什么问题。客户端是Firefox 4或Chrome,两者显示的结果相同。

$.ajax({
         url:url,
         type:'PUT',
         data:'val=' + encodeURIComponent(configValue),
         success: function(data) {...}
       });      

有什么想法吗?

Maybe this is supposed to not work, but at least I'd like to understand why then. I am passing a simple val=somevalue in the PUT body but spring sends back a 400 Bad Request as it does not seem to recognise the val parameter.

Similar request works with POST. Could it be SpringMVC is not recognizing the PUT request body as source for parameters?

Content=-Type is set correctly to application/x-www-form-urlencoded in both cases.

The method that spring refuses to call is this:

@RequestMapping(value = "config/{key}", method = RequestMethod.PUT)
@ResponseBody
public void configUpdateCreate(final Model model, @PathVariable final String key, @RequestParam final String val,
        final HttpServletResponse response) throws IOException
{
    //...
}

For completeness, here is the jquery ajax call. I cannot see anything wrong with that. Client is Firefox 4 or Chrome, both show the same result.

$.ajax({
         url:url,
         type:'PUT',
         data:'val=' + encodeURIComponent(configValue),
         success: function(data) {...}
       });      

Any ideas?

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

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

发布评论

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

评论(4

夜夜流光相皎洁 2024-11-12 01:49:22

我目前不知道有什么解决办法,但这里的错误报告是“无法修复”。我一直在解决同样的问题

https://jira.springsource.org/browse/SPR-7414

更新: 这是我的修复。我正在使用 RequestBody 注释。然后使用MultiValueMap。

http://static.springsource.org/spring/ docs/3.0.5.RELEASE/reference/mvc.html#mvc-ann-requestbody

@RequestMapping(value = "/{tc}", method = RequestMethod.PUT) 
public void update(@PathVariable("tc") final String tc, 
@RequestBody MultiValueMap<String,String> body, HttpServletResponse response) {

    String name = body.getFirst("name");
// more code
}

I don't know of a work around at this point, but here is the bug report that is a "Won't Fix." I've been fighting the same issue

https://jira.springsource.org/browse/SPR-7414

Update: Here is my fix. I'm using RequestBody annotation. Then using MultiValueMap.

http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/mvc.html#mvc-ann-requestbody

@RequestMapping(value = "/{tc}", method = RequestMethod.PUT) 
public void update(@PathVariable("tc") final String tc, 
@RequestBody MultiValueMap<String,String> body, HttpServletResponse response) {

    String name = body.getFirst("name");
// more code
}
不必在意 2024-11-12 01:49:22

Spring 3.1 起,使用 org.springframework.web.filter.HttpPutFormContentFilter

<filter>
    <filter-name>httpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>httpPutFormContentFilter</filter-name>
    <servlet-name>rest</servlet-name>
</filter-mapping>

Since Spring 3.1, this is resolved using org.springframework.web.filter.HttpPutFormContentFilter.

<filter>
    <filter-name>httpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>httpPutFormContentFilter</filter-name>
    <servlet-name>rest</servlet-name>
</filter-mapping>
荒岛晴空 2024-11-12 01:49:22

我没有适合您的解决方案,但在您的情况下,我尝试以下操作:

  • 使用 form:form method="PUT" 创建页面,
  • web 中声明 HiddenHttpMethodFilter .xml

如果这可行,则

  • 在 ajax 调用中将 typePUT 更改为 POST
  • 添加客户端使用 所需的参数代码>表单:表单标签(东西就像_method

换句话说,据我了解,Spring基于带有特殊参数的简单POST来模拟PUT。只要把他想要的东西发给他就可以了。

另请参阅:http://stsmedia.net /spring-finance-part-2-spring-mvc-spring-30-rest-integration/ 以及相关代码示例:http://code.google.com/p/spring-finance-manager/source/browse

HTH

I don't have right solution for you, but in your case I try following:

  • create page with form:form method="PUT"
  • declare HiddenHttpMethodFilter in web.xml

If this will works, then

  • change type from PUT to POST in ajax call
  • add needed params which client has with form:form tag (something like _method)

In other words, as I understand Spring emulates PUT based on simple POST with special parameter. Just send to him what he wants.

See also: http://stsmedia.net/spring-finance-part-2-spring-mvc-spring-30-rest-integration/ and related code examples there: http://code.google.com/p/spring-finance-manager/source/browse

HTH

亚希 2024-11-12 01:49:22

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

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

$.ajax({
            url: "yoururl" + "?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: "yoururl" + "?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.

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