Spring ResponseStatusException

Spring ResponseStatusException

1. Visão geral

Neste tutorial rápido, discutiremos a nova classeResponseStatusException introduzida no Spring 5. Esta classe suporta o aplicativo de códigos de status HTTP para respostas HTTP.

Um aplicativo RESTful pode comunicar o sucesso ou a falha de uma solicitação HTTP porreturning the right status code in the response to the client. Simplificando, um código de status apropriado pode ajudar o cliente a identificar problemas que possam ter ocorrido enquanto o aplicativo estava lidando com a solicitação.

2. ResponseStatus

Antes de nos aprofundarmos emResponseStatusException,, vamos dar uma olhada rápida na anotação@ResponseStatus. Esta anotação foi introduzida no Spring 3 para aplicar o código de status HTTP a uma resposta HTTP.

Podemos usar a anotação@ResponseStatus para definir o status e o motivo em nossa resposta HTTP:

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
    // ...
}

Se essa exceção for lançada durante o processamento de uma solicitação HTTP, a resposta incluirá o status HTTP especificado nesta anotação.

Uma desvantagem da abordagem@ResponseStatus é que ela cria um acoplamento estreito com a exceção. Em nosso exemplo, todas as exceções do tipoActorNotFoundException gerarão a mesma mensagem de erro e código de status na resposta.

3. ResponseStatusException

ResponseStatusException é uma alternativa programática para@ResponseStatus e é a classe base para exceções usadas para aplicar um código de status a uma resposta HTTP. É umRuntimeExceptione, portanto, não é necessário adicionar explicitamente à assinatura de um método.

Spring fornece 3 construtores para gerarResponseStatusException:

ResponseStatusException(HttpStatus status)
ResponseStatusException(HttpStatus status, java.lang.String reason)
ResponseStatusException(
  HttpStatus status,
  java.lang.String reason,
  java.lang.Throwable cause
)

Argumentos do construtorResponseStatusException,:

  • status - um status HTTP definido como resposta HTTP

  • reason - uma mensagem explicando a exceção definida como resposta HTTP

  • causa - uma causaThrowable deResponseStatusException

Nota: no Spring,HandlerExceptionResolver intercepta e processa qualquer exceção levantada e não tratada por um Controlador.

Um desses manipuladores,ResponseStatusExceptionResolver, procura por quaisquerResponseStatusException ou exceções não capturadas anotadas por@ResponseStatus e, em seguida, extrai o código de status HTTP e o motivo e os inclui na resposta HTTP.

3.1. Benefícios deResponseStatusException

ResponseStatusException uso tem poucos benefícios:

  • Em primeiro lugar, exceções do mesmo tipo podem ser processadas separadamente e códigos de status diferentes podem ser definidos na resposta, reduzindo o acoplamento rígido

  • Em segundo lugar, evita a criação de classes de exceção adicionais desnecessárias

  • Por fim, fornece mais controle sobre o tratamento de exceções, pois as exceções podem ser criadas programaticamente

4. Exemplos

4.1. GerarResponseStatusException

Agora, vamos ver um exemplo que gera umResponseStatusException:

@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
    try {
        return actorService.getActor(id);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.NOT_FOUND, "Actor Not Found", ex);
    }
}

Spring Boot fornece um mapeamento/error padrão, retornando uma resposta JSON com status HTTP e a mensagem de exceção.

Aqui está a aparência da resposta:

$ curl -i -s -X GET http://localhost:8080/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 28 Jan 2018 19:48:10 GMT

{
    "timestamp": "2018-01-28T19:48:10.471+0000",
    "status": 404,
    "error": "Not Found",
    "message": "Actor Not Found",
    "path": "/actor/8"
}

4.2. Código de status diferente - mesmo tipo de exceção

Agora, vamos ver como um código de status diferente é definido para resposta HTTP quando o mesmo tipo de exceção é gerado:

@PutMapping("/actor/{id}/{name}")
public String updateActorName(
  @PathVariable("id") int id,
  @PathVariable("name") String name) {

    try {
        return actorService.updateActor(id, name);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex);
    }
}

Aqui está a aparência da resposta:

$ curl -i -s -X PUT http://localhost:8080/actor/8/BradPitt
HTTP/1.1 400
...
{
    "timestamp": "2018-02-01T04:28:32.917+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Provide correct Actor Id",
    "path": "/actor/8/BradPitt"
}

5. Conclusão

Neste tutorial rápido, discutimos como construir umResponseStatusException em nosso programa.

Também enfatizamos como é programaticamente a melhor maneira de definir códigos de status HTTP na resposta HTTP do que a anotação@ResponseStatus.

Como sempre, o código-fonte completo está disponívelover on GitHub.