«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 Not Support — причина, решение
Что мы получаем в этом предыдущем сценарии — ответ 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.