• 8 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 18/02/2022

Gérez les erreurs et validez les données

Gérez les erreurs

Pour introduire la problématique, lançons dans Postman une requête GET vers http://localhost:9090/Produits/42 en indiquant l'Id d'un produit qui n'existe pas. Voici le résultat :

Requête vers un produit inexistant
Requête vers un produit inexistant

Étant donné que ce produit n'existe pas, cette requête ne fournit logiquement pas de réponse.

Avez-vous prêté attention au code de statut retourné ?

Malgré l'absence de réponse, la requête a fourni un code de statut 200 OK. Celui-ci indique que la requête a réussi, c'est-à-dire que le serveur a pu être appelé et n'a retourné aucune erreur particulière. Or, ce comportement peut induire en erreur ou déboussoler tout service extérieur qui viendrait utiliser notre API : il n'y a aucun résultat, mais nous indiquons quand même que tout va bien...

Pour remédier à ceci, nous allons générer une exception lorsqu'on ne trouve pas de produit :

@GetMapping(value = "/Produits/{id}")
public Product afficherUnProduit(@PathVariable int id) {
   Product produit = productDao.findById(id);
      if(produit==null) throw new ProduitIntrouvableException("Le produit avec l'id " + id + " est INTROUVABLE. Écran Bleu si je pouvais.");
   return produit;
}

Si la variable produits est null, nous lançons une exception ProduitIntrouvableException. En effet, nous allons créer notre propre exception afin d'être le plus spécifique possible. 

Dans IntelliJ, ProduitIntrouvableException devrait être rouge car il n'y a pas de classe de ce nom. Cliquez sur ProduitIntrouvableException et une lampe rouge s'affiche à gauche, vous proposant de créer cette exception automatiquement.

Cliquez dessus : une nouvelle fenêtre s'ouvre et vous propose de choisir un package dans lequel placer cette classe. Vous allez changer de package et en indiquer un nouveau, exceptions :

Un nouveau package est créé avec la nouvelle classe. Modifiez cette classe afin qu'elle hérite de RuntimeException. Passez ensuite le message reçu en argument via notre exception et vers la classe parent, pour qu'elle l'intègre dans l'affichage de l'erreur. Voici notre exception finale :

package com.ecommerce.microcommerce.web.exceptions;

public class ProduitIntrouvableException extends RuntimeException 
{
   public ProduitIntrouvableException(String s) 
   {
      super(s);
   }
}

Relancez maintenant votre requête GET sur Postman, vous obtenez donc une erreur en bonne et due forme avec notre petit message personnel :

Affichage du message d'erreur lié à l'exception
Affichage du message d'erreur lié à l'exception

Tout ça est bien joli , mais il y a encore quelque chose qui cloche. Est-ce que vous le voyez ? Il s'agit de l'erreur renvoyée : 500 Internal Server Error. Or, nous n'avons aucun problème de serveur, le problème est que la ressource recherchée est introuvable. Il nous faut donc retourner le code de statut adapté : 404 Not Found.

Nous allons donc modifier notre exception afin qu'elle renvoie le bon code. À cet effet, Spring fournit l'annotation @ResponseStatus qui définit le code de statut associé à l'exception. Modifiez donc votre code comme suit :

package com.ecommerce.microcommerce.web.exceptions;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)

public class ProduitIntrouvableException extends RuntimeException 
{
   public ProduitIntrouvableException(String s) 
   {
      super(s);
   }
}

L'annotation désigne le code d'erreur à renvoyer parmi la liste de tous les codes possibles. Vous pouvez d'ailleurs afficher ces codes dans IntelliJ grâce à l'assistant de code : 

Menu contextuel affichant les codes de statut HTTP disponibles
Menu contextuel affichant les codes de statut HTTP disponibles

Redémarrez et retestez avec Postman :

Affichage du bon code de statut par Postman
Affichage du bon code de statut par Postman

Vous renvoyez ainsi un message d'erreur explicite avec le bon code HTTP.

Effectuez les validations

Jusqu'ici, lorsque nous créons un nouveau Produit grâce à la méthode ajouterProduit, nous  ne vérifions à aucun moment que les données sur le produit sont correctes. Par exemple, la longueur du nom du produit doit être supérieure à 3 caractères, et le prix ne doit jamais être défini à 0 (rien n'est gratuit).

Spring propose de valider les données grâce à une dépendance  spring-boot-starter-validation que je vous laisse ajouter à votre POM : 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.6.0</version>
</dependency>

Cette librairie va vous permettre de valider les données grâce à de simples annotations. Modifions la classe Product en ajoutant les annotations  @Length  et  @Min  , comme suit :

package com.ecommerce.micrommerce.web.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;

//@JsonFilter("monFiltreDynamique")
@Entity
public class Product 
{
   @Id
   private int id;
   @Size(min = 3, max = 25)
   private String nom;
   @Min(value = 1)
   private int prix;
   
…

}

 Explications :

  • @Size : accepte en argument un minimum et un maximum, et vérifie donc si la longueur de la chaîne est conforme.

  • @Min : définit la valeur minimale.

Il nous faut également indiquer dans notre contrôleur que le produit reçu de l'utilisateur est à valider. Pour ce faire, il faut ajouter l'annotation  @Valid  , comme illustré ci-après :

public ResponseEntity<Void> ajouterProduit(@Valid @RequestBody Product product) 
{
  ....
}

Lancez un POST depuis Postman pour tester :

Affichage de l'erreur avec Postman
Affichage de l'erreur avec Postman

Vous voyez le bon code d'erreur : 400 Bad Request.

En résumé

  • Nous savons générer nos entités avec  @Valid  . 

Nous allons maintenant documenter notre API avec Swagger. Allons-y !

Exemple de certificat de réussite
Exemple de certificat de réussite