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.