1. Обзор
Эта короткая статья посвящена распространенной ошибке — «Метод запроса не поддерживается — 405», — с которой сталкиваются разработчики, предоставляя свои API для определенных HTTP-команд с помощью Spring MVC.
Естественно, мы также обсудим распространенные причины этой ошибки.
2. Основы метода запроса
Прежде чем перейти к общей проблеме, если вы только начинаете изучать Spring MVC, вот хорошая вводная статья , с которой можно начать.
Давайте также очень быстро рассмотрим основы — и разберемся в методах запросов, поддерживаемых Spring, и некоторых общих классах, представляющих интерес здесь.
В очень упрощенном виде HTTP-методы MVC представляют собой базовые операции, которые запрос может инициировать на сервере. Например, некоторые методы извлекают
данные с сервера, некоторые отправляют
данные на сервер, некоторые могут удалять
данные и т. д.
Аннотация @RequestMapping
указывает поддерживаемые
методы для запроса.
Spring объявляет все поддерживаемые методы запроса в enum RequestMethod
; он определяет стандартные команды GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
.
Spring DispatcherServlet
по умолчанию `` поддерживает все из них, кроме OPTIONS
и TRACE
; @RequestMapping
использует перечисление RequestMethod
, чтобы указать, какие методы поддерживаются.
3. Простой сценарий MVC
Теперь давайте посмотрим на пример кода, который отображает все методы HTTP:
@RestController
@RequestMapping(value="/api")
public class RequestMethodController {
@Autowired
private EmployeeService service;
@RequestMapping(value = "/employees", produces = "application/json")
public List<Employee> findEmployees()
throws InvalidRequestException {
return service.getEmployeeList();
}
}
Обратите внимание, как в примере объявляется метод findEmployee()
. Он не указывает какой-либо конкретный метод запроса, что означает, что этот URL-адрес поддерживает все методы по умолчанию.
Мы можем запросить API разными поддерживаемыми методами, например, с помощью curl:
$ curl --request POST http://localhost:8080/api/employees
[{"id":100,"name":"Steve Martin","contactNumber":"333-777-999"},
{"id":200,"name":"Adam Schawn","contactNumber":"444-111-777"}]
Естественно, мы можем отправить запрос несколькими способами — через простую команду curl
, Postman, AJAX и т. д.
И, конечно же, мы ожидаем получить ответ 200 OK
, если запрос правильно сопоставлен и выполнен успешно.
4. Сценарий проблемы — HTTP 405
Но то, что мы здесь обсуждаем, — это, конечно же, сценарии, когда запрос не будет успешным.
« 405 Method Not Allowed
» — одна из наиболее распространенных ошибок, которые мы наблюдаем при работе с Spring-запросами.
Давайте посмотрим, что произойдет, если мы специально определим и обработаем запросы GET в Spring MVC, например:
@RequestMapping(
value = "/employees",
produces = "application/json",
method = RequestMethod.GET)
public List<Employee> findEmployees() {
...
}
// send the PUT request using CURL
$ curl --request PUT http://localhost:8080/api/employees
{"timestamp":1539720588712,"status":405,"error":"Method Not Allowed",
"exception":"org.springframework.web.HttpRequestMethodNotSupportedException",
"message":"Request method 'PUT' not supported","path":"/api/employees"}
5. 405 Не поддерживается — причина, решение
То, что мы получаем в этом предыдущем сценарии, — это ответ HTTP с кодом состояния 405 — ошибка клиента, указывающая, что сервер не поддерживает метод/глагол, отправленный в запросе.
Как следует из названия, причиной этой ошибки является отправка запроса неподдерживаемым методом.
Как и следовало ожидать, мы можем решить эту проблему, определив явное сопоставление для PUT в существующем сопоставлении методов:
@RequestMapping(
value = "/employees",
produces = "application/json",
method = {RequestMethod.GET, RequestMethod.PUT}) ...
В качестве альтернативы мы можем определить новый метод/отображение отдельно:
@RequestMapping(value = "/employees",
produces = "application/json",
method=RequestMethod.PUT)
public List<Employee> postEmployees() ...
6. Заключение
Метод/глагол запроса является критическим аспектом HTTP-коммуникации, и нам нужно быть осторожными с точной семантикой операций, которые мы определяем на стороне сервера, а затем с точными запросами, которые мы отправляем.
И, как всегда, примеры, показанные в этой статье, доступны на GitHub .