Método de solicitação não suportado (405) no Spring

Método de solicitação não suportado (405) no Spring

1. Visão geral

Este artigo rápido é focado em um erro comum - ‘Método de solicitação não suportado - 405 '- que os desenvolvedores enfrentam enquanto expõem suas APIs para verbos HTTP específicos, com o Spring MVC.

Naturalmente, também discutiremos as causas comuns desse erro.

2. Noções básicas do método de solicitação

Antes de avançar para o problema comum, se você está começando a aprender sobre o Spring MVC, aqui está um bom https://www..com/spring-mvc-tutorial [artigo de introdução] para começar.

Vamos também dar uma olhada rápida no básico - e entender os métodos de solicitação suportados pelo Spring e algumas das classes de interesse comuns aqui.

De uma maneira altamente simplificada, os métodos HTTP do MVC são operações básicas que uma solicitação pode disparar no servidor. Por exemplo, alguns métodos _ buscar os dados do servidor, alguns _ enviar _ dados para o servidor, alguns podem _ excluir os dados etc.

A anotação https://www..com/spring-requestmapping [@RequestMapping] especifica os métodos suportados para a solicitação.

Spring declara todos os métodos de solicitação suportados em uma enumeração RequestMethod; especifica os verbos padrão GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE.

O https://www..com/spring-dispatcherservlet [Spring DispatcherServlet] suporta todos eles por padrão, exceto OPTIONS e TRACE; @ RequestMapping usa o RequestMethod enum para especificar quais métodos são suportados.

*3. Cenário MVC simples *

Agora, vamos dar uma olhada em um exemplo de código que mapeia todos os métodos 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();
    }
}

Observe como o exemplo declara o método _findEmployee () _. Ele não especifica nenhum método de solicitação específico, o que significa que esse URL suporta todos os métodos padrão.

Podemos solicitar a API usando diferentes métodos suportados, por exemplo, usando 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"}]

Naturalmente, podemos enviar a solicitação de várias maneiras - através de um simples comando curl, Postman, AJAX, etc.

E, é claro, esperamos obter a resposta 200 OK, se a solicitação for mapeada corretamente e for bem-sucedida.

===* 4. Cenário de problema - o HTTP 405 *

Mas, o que estamos discutindo aqui é - é claro - os cenários em que a solicitação não será bem-sucedida.

O método 405 não permitido é um dos erros mais comuns que observamos ao trabalhar com solicitações do Spring.

Vamos dar uma olhada no que acontece se definirmos e manipularmos especificamente as solicitações GET no Spring MVC, desta forma:

@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"}

[[Não suporte - razão, solução

O que estamos obtendo neste cenário anterior é a resposta HTTP com o Código de Status 405 -* um erro do cliente que indica que o servidor não suporta o método/verbo enviado na solicitação. *

Como o nome sugere aqui, o motivo desse erro está enviando a solicitação com um método não suportado.

Como você pode esperar, podemos resolver isso definindo um mapeamento explícito para PUT, no mapeamento de método existente:

@RequestMapping(
  value = "/employees",
  produces = "application/json",
  method = {RequestMethod.GET, RequestMethod.PUT}) ...

Como alternativa, podemos definir o novo método/mapeamento separadamente:

@RequestMapping(value = "/employees",
  produces = "application/json",
  method=RequestMethod.PUT)
public List<Employee> postEmployees() ...

6. Conclusão

O método de solicitação/verbo é um aspecto crítico na comunicação HTTP, e precisamos ter cuidado com a semântica exata das operações que definimos no lado do servidor e com as solicitações exatas que estamos enviando.

E, como sempre, os exemplos mostrados neste artigo estão disponíveis em over no GitHub.