• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 04/02/2020

Gérez les erreurs

Quand nous avons développé le web service LifeLeft, vous avez remarqué que nous avions soigneusement évité de prendre en compte les cas où des erreurs peuvent apparaître. Je pense par exemple au cas ou le service distant fournit à l'opération anneesRestantesAVivre une date de naissance dans le futur par exemple.

Comment sont indiquées les erreurs dans un WSDL ?

Il y a une balise spéciale pour renvoyer une erreur : < fault >. Quand votre service rencontre une exception, il renvoie donc une réponse spéciale de type fault. Fault est un complexType qui se compose éventuellement d'un code d'erreur et d'un message d'erreur.

Nous allons voir comment il est déclaré en détail plus tard quand on aura généré notre WSDL.

Générer une exception

On pourrait croire qu'il suffit de lancer une exception comme on ferait normalement, et que JAX-WS générera la balise fault correspondante. Cela peut marcher mais cela génère beaucoup de problèmes du côté client.

Pour gérer les exceptions correctement, il nous faudra le faire comme le préconisent les spécifications de JAX-WS, c'est-à-dire avec :

  • Une Class POJO dans laquelle nous allons stocker les messages d'erreur. Si vous ne savez pas ce que une Class POJO, c'est une classe basique, qui contient quelques attributs avec leurs getters et setters pour les manipuler, littéralement : Plain Old Java Class. Rien de compliqué.

  • Une Class qui représente notre exception et qui hérite de Exception.

Créez un nouveau package sous le dossier java et appelez-le exceptions.

Commençons par la POJO, créez une Class et nommez-la LifeLeftFault.

package exceptions;

public class LifeLeftFault {

    // code d'erreur
    private String faultCode;

    //message d'erreur
    private String faultString;

    //Tous les getters et setters des 2 attributs précédentes

    public String getFaultCode() {
        return faultCode;
    }

    public void setFaultCode(String faultCode) {
        this.faultCode = faultCode;
    }

    public String getFaultString() {
        return faultString;
    }

    public void setFaultString(String faultString) {
        this.faultString = faultString;
    }
}

C'est une classe toute simple pour contenir les détails de l'erreur que nous allons retourner.

Créez une Class et nommez-la LeftLifeException, celle-ci contiendra le code de notre exception proprement dite. Cette Class doit répondre à des critères précis :

  • Être annotée avec @WebFault

  • Hériter de Exception

  • Avoir 2 constructeurs minimum

  • Avoir la méthode getFaultInfo qui retourne la POJO déjà créée

On obtient donc ceci :

package exceptions;

import javax.xml.ws.WebFault;

@WebFault(name = "LifeLeftException")
public class LifeLeftException extends Exception {

    /*
    on déclare une instance de LifeLeftFault qu'on créée précédemment
    afin de récupérer ensuite les messages et codes d'erreurs à renvoyer dans cette exception
     */
    private LifeLeftFault fault;

    /*
    On crée un constructeur qui prend en paramètre un message d'erreur et un objet LifeLeftFault
    avec plus de détails sur l'erreur
    */
    public LifeLeftException(String message, LifeLeftFault fault) {
        super(message);
        this.fault = fault;
    }

    public LifeLeftException(String message, Throwable cause, LifeLeftFault fault) {
        super(message, cause);
        this.fault = fault;
    }

    public LifeLeftFault getFaultInfo() {
        return fault;
    }
}

Le rôle du deuxième constructeur est de nous permettre de générer des exceptions sans le POJO en passant un Throwable à la place, afin de pouvoir utiliser les exceptions classiques de Java.

Vous devriez avoir l'arborescence suivante :

Figure 1
Figure 1

Il ne reste plus qu'à utiliser cette classe pour générer une exception quand le paramètre naissance est supérieur à 2017 par exemple.

@WebMethod
    public String  anneesRestantesAVivre (String prenom, String genre, Integer anneeNaissance) throws LifeLeftException {

        //vaut mieux remplacer 2017 par Year.now().getValue(), mais pour simplifier on laisse 2017
        if(anneeNaissance > 2017) {

            //On créer une nouvelle instance de notre POJO
            LifeLeftFault fault = new LifeLeftFault();

            //On y ajoute le code d'erreur et le détail de l'erreur en question
            fault.setFaultCode("1234");
            fault.setFaultString("L'année reçu est supérieur l'année actuelle");

            //on lance l'exception avec comme premier argument un message général sur l'erreur.
            throw new LifeLeftException("Année invalide", fault);
        }

        if(genre.equals(homme)) evDeReference = ESPERANCE_VIE_HOMMES;
        else evDeReference = ESPERANCE_VIE_FEMMES;

        //Remarque, en cas de problème, vous pouvez changer Year.now().getValue() par Calendar.getInstance().get(Calendar.YEAR)
        Integer anneeRestantes = evDeReference -(Year.now().getValue() - anneeNaissance );



        return "Bonjour " + prenom + ", il vous reste " + anneeRestantes + " ans, à vivre, Profitez-en au maximum !";
    }

Comme je l'ai indiqué dans les commentaires, on alimente le POJO avec les messages appropriés puis on le passe en argument à l'exception à retourner.

C'est fini ! Faites dans le panneau latéral de Maven un Clean puis un Install et uploadez le War sur Glassfish.

Tester

Retournez à SoapUI dans le projet LifeLeft. Allez cette fois dans TestSuite 2 que nous avons créé précédemment et double cliquez sur anneesRestantesAVivre. Remplissez les balises avec les arguments nécessaires en veillent à mettre une année supérieure à 2017 puis cliquez sur play.

Figure 2
Figure 2

Vous devriez alors avoir une balise fault en réponse avec faultstring contenant le message général qu'on a défini en premier argument de notre exception et les détails de l'erreur sous la balise detail.

Le WSDL

Rendez-vous à l'URL du WSDL de LifeLeft http://localhost:8080/lifeleft/LifeLeft?wsdl. Vous constaterez que pour gérer l'exception, les éléments suivants ont été ajoutés :

  • Sous < types > si vous allez au lien de schemaLocation qui contient les types complexes, vous verrez alors qu'un nouveau type complexe a été ajouté :

    <xs:complexType name="lifeLeftFault">
    <xs:sequence>
      <xs:element name="faultCode" type="xs:string" minOccurs="0"/>
      <xs:element name="faultString" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    </xs:complexType>
  • Sous portType l'opération anneesRestantesAVivre a maintenant, en plus des input et output classiques, une autre possibilité de réponse : fault.

  • Cette dernière réponse possible est répercutée comme toutes les autres sous binding.

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