SpringMVC is not recognizing request body paramete

2019-01-13 05:33发布

问题:

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?

回答1:

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
}


回答2:

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>


回答3:

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



回答4:

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.