Может ли Spring MVC иметь параметры запроса для метода HTTP PUT или использовать пост? Что я должен использовать для RESTful?
У меня есть действие контроллера, я думаю, должен быть 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
, но не создает его.
Ответы
Ответ 1
Поскольку Spring 3.1, HttpPutFormContentFilter может использоваться для обработки данных application/x-www-form-urlencoded
:
Фильтр, который формирует кодированные данные формы через семейство методов ServletRequest.getParameter*()
во время запросов HTTP PUT.
Спецификация Servlet требует, чтобы данные формы были доступны для HTTP POST, но не для запросов HTTP PUT. Этот фильтр перехватывает HTTP-запросы PUT, где тип контента 'application/x-www-form-urlencoded'
, считывает кодированный текст из тела запроса и обертывает ServletRequest, чтобы сделать данные формы доступными как параметры запроса так же, как и запросы HTTP POST.
Для других входящих данных, таких как JSON, вам понадобится @RequestBody
, как описано в JQuery, Spring MVC @RequestBody и JSON - что позволяет работать вместе, чтобы не работать с 415 неподдерживаемым типом носителя.
Ответ 2
Контроллеры Spring поддерживают GET/HEAD/POST/PUT/DELETE/OPTIONS/TRACE, но поскольку ваш браузер не сможет отправлять эти методы запроса, он не будет работать для вас.
Обходным путем является использование "org.springframework.web.filter.HiddenHttpMethodFilter" , предоставляемый Spring. Для этого требуется передать скрытый параметр для метода запроса. Параметр по умолчанию, поддерживаемый этим фильтром, является "_method".
Проверьте javadoc фильтра для получения дополнительной информации.
Ответ 3
Это, как указано выше, кажется ошибкой в 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. Надеюсь это поможет.
Ответ 4
Я следил за рекомендацией в комментариях и менял @RequestParam
на @RequestBody
, и он просто работал (мой параметр - String).
Я согласен, что это ошибка в Spring, потому что тот же самый код, который не работает в моей рабочей среде (при использовании @RequestParam
), отлично работает в localhost.