【问题标题】:SpringMVC is not recognizing request body parameters if using PUT如果使用 PUT,SpringMVC 无法识别请求正文参数
【发布时间】:2011-05-05 07:42:10
【问题描述】:

也许这应该行不通,但至少我想明白为什么。我在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) {...}
       });      

有什么想法吗?

【问题讨论】:

  • 将其更改为 POST 是否有效?
  • 为什么在void方法中用@ResponseBody注解方法?该注释应该指示返回类型应直接写入 HTTP 响应正文。我认为情况并非如此。您也可以尝试这样做: data:{'val', encodeURIComponent(configValue)},
  • 400代码返回的错误信息是什么?

标签: jquery rest spring-mvc


【解决方案1】:

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

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
}

【讨论】:

  • 感谢 Tomcat 列表上讨论的链接,它澄清了问题。在我的情况下,带有 @RequestBody 注释的解决方案不适用于自定义模型/表单支持 bean 类,而不是多映射。所以我正在使用 HiddenHttpMethodFilter 并且我正在从 jQuery 发送一个 POST 请求,其中包括一个 _method=put 参数,正如 php-coder 所建议的那样。
【解决方案2】:

Since 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>

【讨论】:

  • 这将进入您的 web.xml
【解决方案3】:

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

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

如果这行得通,那么

  • 在 ajax 调用中将 typePUT 更改为 POST
  • 使用form:form 标签添加客户端所需的参数(类似于_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

【讨论】:

    【解决方案4】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多