Может ли Spring MVC иметь параметры запроса для метода HTTP PUT или я должен использовать post? Что я должен использовать, чтобы быть 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
, но это не создает.
4 ответа
Начиная с весны 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 неподдерживаемым типом носителя.
Контроллеры Spring поддерживают GET/HEAD/POST/PUT/DELETE/OPTIONS/TRACE, но, поскольку ваш браузер не может отправлять эти методы запроса, он не будет работать для вас.
Обходной путь должен использовать "org.springframework.web.filter.HiddenHttpMethodFilter", предоставленный Spring. Требуется передать скрытый параметр для метода запроса. Параметр по умолчанию, поддерживаемый этим фильтром, - "_method".
Проверьте javadoc фильтра для получения дополнительной информации.
Это, как показано выше, похоже, ошибка в 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. Надеюсь это поможет.
Я последовал рекомендации в комментариях и изменил @RequestParam
в @RequestBody
и это просто сработало (мой параметр - строка).
Я согласен, что это ошибка в Spring, потому что тот же код не работает в моей производственной среде (при использовании @RequestParam
) отлично работает в localhost.