«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.