Может ли Spring MVC иметь параметры запроса для метода HTTP PUT или я должен использовать post? Что я должен использовать, чтобы быть RESTful? - PullRequest
19 голосов
/ 24 ноября 2011

У меня есть действие контроллера, которое, я думаю, должно быть HTTP PUT, но Spring жалуется, когда я пытаюсь использовать @RequestParam в действии контроллера. Разрешены ли параметры запроса для методов 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, но не создает его.

Ответы [ 4 ]

15 голосов
/ 28 января 2013

Начиная с Spring 3.1, HttpPutFormContentFilter может использоваться для обработки application/x-www-form-urlencoded данных:

Фильтр, который делает закодированные данные формы доступными через ServletRequest.getParameter*() семейство методов во время запросов HTTP PUT.

Спецификация сервлета требует, чтобы данные формы были доступны для HTTP POST, но не для запросов HTTP PUT.Этот фильтр перехватывает запросы HTTP PUT с типом содержимого 'application/x-www-form-urlencoded', считывает закодированное из формы содержимое из тела запроса и упаковывает запрос ServletRequest, чтобы сделать данные формы доступными в качестве параметров запроса, точно так же, как и для запросов HTTP POST.

Для других входящих данных, таких как JSON, вам потребуется @RequestBody, как описано в JQuery, Spring MVC @RequestBody и JSON - чтобы они работали вместе , чтобы не запускатьв неподдерживаемый тип носителя 415.

6 голосов
/ 05 декабря 2011

Контроллеры Spring поддерживают GET / HEAD / POST / PUT / DELETE / OPTIONS / TRACE, но, поскольку ваш браузер не может отправлять эти методы запроса, он не будет работать для вас.используйте "org.springframework.web.filter.HiddenHttpMethodFilter" , предоставленный Spring.Требуется передать скрытый параметр для метода запроса.Параметр по умолчанию, поддерживаемый этим фильтром, - «_method».

Для получения дополнительной информации проверьте javadoc фильтра.

3 голосов
/ 20 января 2012

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

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

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

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

0 голосов
/ 26 января 2015

Я следовал рекомендации в комментариях и изменил @RequestParam на @RequestBody, и это просто сработало (мой параметр - строка).

Я согласен, что это ошибка в Spring, потому что тот же кодкоторая не работает в моей производственной среде (при использовании @RequestParam), отлично работает в localhost.

...