Spring ResponseStatusException

Spring ResponseStatusException

1. Vue d'ensemble

Dans ce rapide didacticiel, nous aborderons la nouvelle classeResponseStatusException introduite au printemps 5. Cette classe prend en charge l’application de codes d’état HTTP aux réponses HTTP.

Une application RESTful peut communiquer le succès ou l'échec d'une requête HTTP parreturning the right status code in the response to the client. En termes simples, un code d'état approprié peut aider le client à identifier les problèmes pouvant survenir pendant que l'application traitait la demande.

2. ResponseStatus

Avant de plonger dansResponseStatusException,, examinons rapidement l'annotation@ResponseStatus. Cette annotation a été introduite au printemps 3 pour appliquer le code d'état HTTP à une réponse HTTP.

Nous pouvons utiliser l'annotation@ResponseStatus pour définir le statut et la raison dans notre réponse HTTP:

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

Si cette exception est levée lors du traitement d'une requête HTTP, la réponse inclura le statut HTTP spécifié dans cette annotation.

Un inconvénient de l'approche@ResponseStatus est qu'elle crée un couplage étroit à l'exception. Dans notre exemple, toutes les exceptions de typeActorNotFoundException généreront le même message d'erreur et le même code d'état dans la réponse.

3. ResponseStatusException

ResponseStatusException est une alternative par programme à@ResponseStatus et est la classe de base pour les exceptions utilisées pour appliquer un code d'état à une réponse HTTP. C'est unRuntimeException et il n'est donc pas nécessaire de l'ajouter explicitement dans une signature de méthode.

Spring fournit 3 constructeurs pour générer desResponseStatusException:

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

Arguments du constructeur deResponseStatusException,:

  • status - statut HTTP défini sur une réponse HTTP

  • reason - un message expliquant l'exception définie sur la réponse HTTP

  • cause - une causeThrowable desResponseStatusException

Remarque: dans Spring,HandlerExceptionResolver intercepte et traite toute exception levée et non gérée par un contrôleur.

L'un de ces gestionnaires,ResponseStatusExceptionResolver, recherche les exceptionsResponseStatusException ou non interceptées annotées par@ResponseStatus, puis extrait le code d'état HTTP et la raison et les inclut dans la réponse HTTP.

3.1. Avantages deResponseStatusException

L'utilisation deResponseStatusException présente peu d'avantages:

  • Tout d'abord, des exceptions du même type peuvent être traitées séparément et différents codes d'état peuvent être définis sur la réponse, ce qui réduit le couplage étroit

  • Deuxièmement, cela évite la création de classes d'exceptions supplémentaires inutiles

  • Enfin, il offre davantage de contrôle sur la gestion des exceptions, car les exceptions peuvent être créées par programme.

4. Exemples

4.1. GénérerResponseStatusException

Voyons maintenant un exemple qui génère unResponseStatusException:

@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 fournit un mappage par défaut/error, renvoyant une réponse JSON avec l'état HTTP et le message d'exception.

Voici à quoi ressemble la réponse:

$ 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. Code d'état différent - Même type d'exception

Voyons maintenant comment un code d'état différent est défini sur la réponse HTTP lorsque le même type d'exception est déclenché:

@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);
    }
}

Voici à quoi ressemble la réponse:

$ 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. Conclusion

Dans ce rapide tutoriel, nous avons expliqué comment construire unResponseStatusException dans notre programme.

Nous avons également insisté sur le fait qu'il s'agit d'un meilleur moyen par programme de définir les codes d'état HTTP dans la réponse HTTP que l'annotation@ResponseStatus.

Comme toujours, le code source complet est disponibleover on GitHub.