SpringMVC не распознает параметры тела запроса при использовании PUT

Может быть, это должно сработать, но, по крайней мере, я хотел бы понять, почему тогда. Я передаю простой val=somevalue в PUT тело, но весна отправляет обратно 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) {...}
       });      

Есть идеи?

4 ответа

Решение

На данный момент я не знаю, как это обойти, но вот отчет об ошибке, который называется "Не исправлю". Я боролся с той же проблемой

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

Обновление: вот мое исправление. Я использую аннотацию RequestBody. Затем с помощью MultiValueMap.

http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/mvc.html

@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
}

Начиная с Spring 3.1, это решается с помощью http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/web/filter/HttpPutFormContentFilter.html.

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

Это, как показано выше, похоже, ошибка в spring/servlet API, В действительности PUT запросы должны работать на Request Body (or payload) а не по параметрам запроса. В этом смысле API сервлетов и обработка Spring правильны.

Сказав это, лучше и проще обойти это, не передавая элемент данных из вашего javascript/jQuery вызовите и передайте ваши параметры как часть самого URL. То есть, установите параметры в поле URL, как вы бы сделали в GET вызов.

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

теперь это работает для простых параметров, я думаю, не будет работать для сложных типов JSON. Надеюсь это поможет.

У меня нет правильного решения для вас, но в вашем случае я стараюсь сделать следующее:

  • создать страницу с form:form method="PUT"
  • объявлять HiddenHttpMethodFilter в web.xml

Если это будет работать, то

  • менять type от PUT в POST в вызове ajax
  • добавить необходимые параметры, которые есть у клиента form:form тег (что-то вроде _method)

Другими словами, как я понимаю, Spring подражает PUT основанный на простом POST со специальным параметром. Просто пошли ему то, что он хочет.

См. Также: http://stsmedia.net/spring-finance-part-2-spring-mvc-spring-30-rest-integration/ и соответствующие примеры кода: http://code.google.com/p/spring -Финанс-менеджер / источник / просмотреть

НТН

Другие вопросы по тегам