Mis à jour le vendredi 10 mars 2017
  • 40 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

TP Fil rouge - Étape 1

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Comme je vous l’annonçais en avant-propos, vous êtes ici pour apprendre à créer un projet web, en y ajoutant de la complexité au fur et à mesure que le cours avance. Avec tout ce que vous venez de découvrir, vous voici prêts pour poser la première pierre de l'édifice ! Je vous propose, dans cette première étape de notre TP fil rouge qui vous accompagnera jusqu'au terme de votre apprentissage, de revoir et appliquer l'ensemble des notions abordées jusqu'à présent.

Objectifs

Contexte

J'ai choisi la thématique du commerce en ligne comme source d'inspiration : vous allez créer un embryon d'application qui va permettre la création et la visualisation de clients et de commandes. C'est à la fois assez global pour ne pas impliquer d'éléments qui vous sont encore inconnus, et assez spécifique pour coller avec ce que vous avez appris dans ces chapitres et êtes capables de réaliser.

L'objectif premier de cette étape, c'est de vous familiariser avec le développement web sous Eclipse. Vous allez devoir mettre en place un projet en partant de zéro dans votre environnement, et y créer vos différents fichiers. Le second objectif est que vous soyez à l'aise avec l'utilisation de servlets, de pages JSP et de beans, et de manière générale avec le principe général d'une application Java EE.

Fonctionnalités

Création d'un client

À travers notre petite application, l'utilisateur doit pouvoir créer un client en saisissant des données depuis un formulaire, et visualiser la fiche client en résultant. Puisque vous n'avez pas encore découvert les formulaires, je vais vous fournir une page qui vous servira de base. Votre travail sera de coder :

  • un bean, représentant un client ;

  • une servlet, chargée de récupérer les données envoyées par le formulaire, de les enregistrer dans le bean et de les transmettre à une JSP ;

  • une JSP, chargée d'afficher la fiche du client créé, c'est-à-dire les données transmises par la servlet.

Création d'une commande

L'utilisateur doit également pouvoir créer une commande, en saisissant des données depuis un formulaire, et visualiser la fiche en résultant. De même, puisque vous n'avez pas encore découvert les formulaires, je vais vous fournir une page qui vous servira de base. Votre travail sera de coder :

  • un bean, représentant une commande ;

  • une servlet, chargée de récupérer les données envoyées par le formulaire, de les enregistrer dans le bean et de les transmettre à une JSP ;

  • une JSP, chargée d'afficher la fiche de la commande créée, c'est-à-dire les données transmises par la servlet.

Contraintes

Comme je viens de vous l'annoncer, vous devez utiliser ces deux formulaires comme base pour votre application. Vous les placerez directement à la racine de votre application, sous le répertoire WebContent d'Eclipse.

Création d'un client
<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Création d'un client</title>
        <link type="text/css" rel="stylesheet" href="inc/style.css" />
    </head>
    <body>
        <div>
            <form method="get" action="creationClient">
                <fieldset>
                    <legend>Informations client</legend>
    
                    <label for="nomClient">Nom <span class="requis">*</span></label>
                    <input type="text" id="nomClient" name="nomClient" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="prenomClient">Prénom </label>
                    <input type="text" id="prenomClient" name="prenomClient" value="" size="20" maxlength="20" />
                    <br />
    
                    <label for="adresseClient">Adresse de livraison <span class="requis">*</span></label>
                    <input type="text" id="adresseClient" name="adresseClient" value="" size="20" maxlength="20" />
                    <br />
    
                    <label for="telephoneClient">Numéro de téléphone <span class="requis">*</span></label>
                    <input type="text" id="telephoneClient" name="telephoneClient" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="emailClient">Adresse email</label>
                    <input type="email" id="emailClient" name="emailClient" value="" size="20" maxlength="60" />
                    <br />
                </fieldset>
                <input type="submit" value="Valider"  />
                <input type="reset" value="Remettre à zéro" /> <br />
            </form>
        </div>
    </body>
</html>
Création d'une commande
<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Création d'une commande</title>
        <link type="text/css" rel="stylesheet" href="inc/style.css" />
    </head>
    <body>
        <div>
            <form method="get" action="creationCommande">
                <fieldset>
                    <legend>Informations client</legend>
    
                    <label for="nomClient">Nom <span class="requis">*</span></label>
                    <input type="text" id="nomClient" name="nomClient" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="prenomClient">Prénom </label>
                    <input type="text" id="prenomClient" name="prenomClient" value="" size="20" maxlength="20" />
                    <br />
    
                    <label for="adresseClient">Adresse de livraison <span class="requis">*</span></label>
                    <input type="text" id="adresseClient" name="adresseClient" value="" size="20" maxlength="20" />
                    <br />
    
                    <label for="telephoneClient">Numéro de téléphone <span class="requis">*</span></label>
                    <input type="text" id="telephoneClient" name="telephoneClient" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="emailClient">Adresse email</label>
                    <input type="email" id="emailClient" name="emailClient" value="" size="20" maxlength="60" />
                    <br />
                </fieldset>
                <fieldset>
                    <legend>Informations commande</legend>
                    
                    <label for="dateCommande">Date <span class="requis">*</span></label>
                    <input type="text" id="dateCommande" name="dateCommande" value="" size="20" maxlength="20" disabled />
                    <br />
                    
                    <label for="montantCommande">Montant <span class="requis">*</span></label>
                    <input type="text" id="montantCommande" name="montantCommande" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="modePaiementCommande">Mode de paiement <span class="requis">*</span></label>
                    <input type="text" id="modePaiementCommande" name="modePaiementCommande" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="statutPaiementCommande">Statut du paiement</label>
                    <input type="text" id="statutPaiementCommande" name="statutPaiementCommande" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="modeLivraisonCommande">Mode de livraison <span class="requis">*</span></label>
                    <input type="text" id="modeLivraisonCommande" name="modeLivraisonCommande" value="" size="20" maxlength="20" />
                    <br />
                    
                    <label for="statutLivraisonCommande">Statut de la livraison</label>
                    <input type="text" id="statutLivraisonCommande" name="statutLivraisonCommande" value="" size="20" maxlength="20" />
                    <br />
                </fieldset>
                <input type="submit" value="Valider"  />
                <input type="reset" value="Remettre à zéro" /> <br />
            </form>
        </div>
    </body>
</html>
Feuille de style

Voici pour finir une feuille de style que je vous propose d'utiliser pour ce TP. Toutefois, si vous êtes motivés vous pouvez très bien créer et utiliser vos propres styles, cela n'a pas d'importance.

/* Général ------------------------------------------------------------------------------------- */

body, p, legend, label, input {
    font: normal 8pt verdana, helvetica, sans-serif;
}

/* Forms --------------------------------------------------------------------------------------- */
fieldset {
    padding: 10px;
    border: 1px #0568CD solid;
    margin: 10px;
}

legend {
    font-weight: bold;
    color: #0568CD;
}

form label {
    float: left;
    width: 200px;
    margin: 3px 0px 0px 0px;
}

form input {
    margin: 3px 3px 0px 0px;
    border: 1px #999 solid;
}

form input.sansLabel {
    margin-left: 200px;
}

/* Styles et couleurs -------------------------------------------------------------------------- */
.requis {
    color: #c00;
}

.erreur {
    color: #900;
}

.succes {
    color: #090;
}

.info {
    font-style: italic;
    color: #E8A22B;
}

Conseils

À propos des formulaires

Voici les seules informations que vous devez connaître pour attaquer :

  • ces deux formulaires sont configurés pour envoyer les données saisies vers les adresses /creationClient et /creationCommande. Lorsque vous mettrez en place vos deux servlets, vous devrez donc effectuer un mapping respectivement sur chacune de ces deux adresses dans votre fichier web.xml ;

  • les données seront envoyées via la méthode GET du protocole HTTP, vous devrez donc implémenter la méthode doGet() dans vos servlets ;

  • le nom des paramètres créés lors de l'envoi des données correspond au contenu des attributs "name" de chaque balise <input> des formulaires. Par exemple, le nom du client étant saisi dans la balise <input name="nomClient"... /> du formulaire, il sera accessible depuis votre servlet par un appel à request.getParameter("nomClient") ;

  • j'ai volontairement désactivé le champ de saisie de la date dans le formulaire de création d'une commande. Nous intégrerons bien plus tard un petit calendrier permettant le choix d'une date, mais pour le moment nous ferons sans.

Le modèle

Vous n'allez travailler que sur deux entités, à savoir un client et une commande. Ainsi, deux objets suffiront :

  • un bean Client représentant les données récupérées depuis le formulaire creerClient.jsp (nom, prénom, adresse, etc.) ;

  • un bean Commande représentant les données récupérées depuis la seconde partie du formulaire creerCommande.jsp (date, montant, mode de paiement, etc.).

N'hésitez pas à relire le chapitre sur les Javabeans pour vous rafraîchir la mémoire sur leur structure.

Note 1 : au sujet du type des propriétés de vos beans, je vous conseille de toutes les déclarer de type String, sauf le montant de la commande que vous pouvez éventuellement déclarer de type double.
Note 2 : lors de la création d'une commande, l'utilisateur va devoir saisir des informations relatives au client. Plutôt que de créer une propriété pour chaque champ relatif au client (nom, prénom, adresse, etc.) dans votre bean Commande, vous pouvez directement y inclure une propriété de type Client, qui à son tour contiendra les propriétés nom, prénom, etc.

Les contrôleurs

Les deux formulaires que je vous fournis sont paramétrés pour envoyer les données saisies au serveur par le biais d'une requête de type GET. Vous aurez donc à créer deux servlets, que vous pouvez par exemple nommer CreationClient et CreationCommande, qui vont pour chaque formulaire :

  • récupérer les paramètres saisis, en appelant request.getParameter() sur les noms des différents champs ;

  • les convertir dans le type souhaité si certaines des propriétés de vos beans ne sont pas des String, puis les enregistrer dans le bean correspondant ;

  • vérifier si l'utilisateur a oublié de saisir certains paramètres requis (ceux marqués d'une étoile sur le formulaire de saisie) :

    • si oui, alors transmettre les beans et un message d'erreur à une page JSP pour affichage ;

    • si non, alors transmettre les beans et un message de succès à une page JSP pour affichage.

Puisque le champ de saisie de la date est désactivé, vous allez devoir initialiser la propriété date du bean Commande avec la date courante. Autrement dit, vous allez considérer que la date d'une commande est simplement la date courante lors de la validation du formulaire. Vous devrez donc récupérer directement la date courante depuis votre servlet et l'enregistrer au format String dans le bean.

Les vues

Je vous fournis les deux pages JSP contenant les formulaires de saisie des données. Les seules vues que vous avez à développer sont celles qui affichent les données saisies, après validation du formulaire. Vous pouvez par exemple les nommer afficherClient.jsp et afficherCommande.jsp. Elles vont recevoir un ou plusieurs beans et un message depuis leur servlet respective, et devront afficher les données contenues dans ces objets. Vous l'avez probablement déjà deviné, les expressions EL sont la solution idéale ici !

Vous êtes libres au niveau de la mise en forme des données et des messages affichés ; ce qui importe n'est pas le rendu graphique de vos pages, mais bien leur capacité à afficher correctement ce qu'on attend d'elles ! ;)

Création du projet

Avant de vous lâcher dans la nature, revenons rapidement sur la mise en place du projet. N'hésitez pas à relire le chapitre sur la configuration d'un projet si vous avez encore des incertitudes à ce sujet. Je vous conseille de créer un projet dynamique en partant de zéro dans Eclipse, que vous pouvez par exemple nommer tp1, basé sur le serveur Tomcat 7 que nous avons déjà mis en place dans le cadre du cours. Vous devrez alors configurer le build-path comme nous avons appris à le faire dans le chapitre sur les Javabeans. Vous allez par ailleurs devoir manipuler une date lors de la création d'une commande : je vous encourage pour cela à utiliser la bibliothèque JodaTime que nous avons découverte dans le chapitre précédent.

Pour conclure, voici à la figure suivante ce à quoi est supposée ressembler l'architecture de votre projet fini si vous avez suivi mes conseils et exemples de nommage.

Image utilisateur

Vous pouvez observer en encadré sur cette image le positionnement des trois fichiers dont je vous ai fourni le code.

Illustration du comportement attendu

À la figure suivante, voici sous forme d'un schéma ce que vous devez réaliser dans le cas de la création d'un client.

Image utilisateur

Je ne vous illustre pas la création d'une commande, le principe étant très similaire !

Exemples de rendu du comportement attendu

Création d'un client

Avec succès (voir les figures suivantes).

Saisie de données valides dans le formulaire
Saisie de données valides dans le formulaire
Affichage du message de succès et des données
Affichage du message de succès et des données

Avec erreur (voir les figures suivantes).

Oubli d'un champ obligatoire dans le formulaire
Oubli d'un champ obligatoire dans le formulaire
Affichage du message d'erreur et des données
Affichage du message d'erreur et des données
Création d'une commande

Avec succès (voir les figures suivantes).

Saisie de données valides dans le formulaire
Saisie de données valides dans le formulaire
Affichage du message de succès et des données
Affichage du message de succès et des données

Avec erreur (voir les figures suivantes).

Oubli de champs obligatoires et saisie d'un montant erroné dans le formulaire
Oubli de champs obligatoires et saisie d'un montant erroné dans le formulaire
Affichage du message d'erreur et des données
Affichage du message d'erreur et des données

Correction

Je vous propose cette solution en guise de correction. Ce n'est pas la seule manière de faire. Ne vous inquiétez pas si vous avez procédé différemment, si vous avez nommé vos objets différemment ou si vous avez bloqué sur certains éléments. Le code est commenté et vous est parfaitement accessible : il ne contient que des instructions et expressions que nous avons déjà abordées dans les chapitres précédents.

Le code des beans

package com.sdzee.tp.beans;

public class Client {
    /* Propriétés du bean */
    private String nom;
    private String prenom;
    private String adresse;
    private String telephone;
    private String email;

    public void setNom( String nom ) {
        this.nom = nom;
    }

    public String getNom() {
        return nom;
    }

    public void setPrenom( String prenom ) {
        this.prenom = prenom;
    }

    public String getPrenom() {
        return prenom;
    }

    public void setAdresse( String adresse ) {
        this.adresse = adresse;
    }

    public String getAdresse() {
        return adresse;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone( String telephone ) {
        this.telephone = telephone;
    }

    public void setEmail( String email ) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }
}
package com.sdzee.tp.beans;


public class Commande {
    /* Propriétés du bean */
    private Client client;
    private String date;
    private Double montant;
    private String modePaiement;
    private String statutPaiement;
    private String modeLivraison;
    private String statutLivraison;

    public Client getClient() {
        return client;
    }

    public void setClient( Client client ) {
        this.client = client;
    }

    public String getDate() {
        return date;
    }

    public void setDate( String date ) {
        this.date = date;
    }

    public Double getMontant() {
        return montant;
    }

    public void setMontant( Double montant ) {
        this.montant = montant;
    }

    public String getModePaiement() {
        return modePaiement;
    }

    public void setModePaiement( String modePaiement ) {
        this.modePaiement = modePaiement;
    }

    public String getStatutPaiement() {
        return statutPaiement;
    }

    public void setStatutPaiement( String statutPaiement ) {
        this.statutPaiement = statutPaiement;
    }

    public String getModeLivraison() {
        return modeLivraison;
    }

    public void setModeLivraison( String modeLivraison ) {
        this.modeLivraison = modeLivraison;
    }

    public String getStatutLivraison() {
        return statutLivraison;
    }

    public void setStatutLivraison( String statutLivraison ) {
        this.statutLivraison = statutLivraison;
    }
}

Le code des servlets

Configuration des servlets dans le fichier web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<servlet>
		<servlet-name>CreationClient</servlet-name>
		<servlet-class>com.sdzee.tp.servlets.CreationClient</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>CreationCommande</servlet-name>
		<servlet-class>com.sdzee.tp.servlets.CreationCommande</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>CreationClient</servlet-name>
		<url-pattern>/creationClient</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>CreationCommande</servlet-name>
		<url-pattern>/creationCommande</url-pattern>
	</servlet-mapping>
</web-app>

Servlet gérant le formulaire de création d'un client :

package com.sdzee.tp.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sdzee.tp.beans.Client;

public class CreationClient extends HttpServlet {

    public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
        /*
         * Récupération des données saisies, envoyées en tant que paramètres de
         * la requête GET générée à la validation du formulaire
         */
        String nom = request.getParameter( "nomClient" );
        String prenom = request.getParameter( "prenomClient" );
        String adresse = request.getParameter( "adresseClient" );
        String telephone = request.getParameter( "telephoneClient" );
        String email = request.getParameter( "emailClient" );

        String message;
        /*
         * Initialisation du message à afficher : si un des champs obligatoires
         * du formulaire n'est pas renseigné, alors on affiche un message
         * d'erreur, sinon on affiche un message de succès
         */
        if ( nom.trim().isEmpty() || adresse.trim().isEmpty() || telephone.trim().isEmpty() ) {
            message = "Erreur - Vous n'avez pas rempli tous les champs obligatoires. <br> <a href=\"creerClient.jsp\">Cliquez ici</a> pour accéder au formulaire de création d'un client.";
        } else {
            message = "Client créé avec succès !";
        }
        /*
         * Création du bean Client et initialisation avec les données récupérées
         */
        Client client = new Client();
        client.setNom( nom );
        client.setPrenom( prenom );
        client.setAdresse( adresse );
        client.setTelephone( telephone );
        client.setEmail( email );

        /* Ajout du bean et du message à l'objet requête */
        request.setAttribute( "client", client );
        request.setAttribute( "message", message );

        /* Transmission à la page JSP en charge de l'affichage des données */
        this.getServletContext().getRequestDispatcher( "/afficherClient.jsp" ).forward( request, response );
    }
}

Servlet gérant le formulaire de création d'une commande :

package com.sdzee.tp.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.sdzee.tp.beans.Client;
import com.sdzee.tp.beans.Commande;

public class CreationCommande extends HttpServlet {

    public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
        /*
         * Récupération des données saisies, envoyées en tant que paramètres de
         * la requête GET générée à la validation du formulaire
         */
        String nom = request.getParameter( "nomClient" );
        String prenom = request.getParameter( "prenomClient" );
        String adresse = request.getParameter( "adresseClient" );
        String telephone = request.getParameter( "telephoneClient" );
        String email = request.getParameter( "emailClient" );

        /* Récupération de la date courante */
        DateTime dt = new DateTime();
        /* Conversion de la date en String selon le format défini */
        DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy HH:mm:ss" );
        String date = dt.toString( formatter );
        double montant;
        try {
            /* Récupération du montant */
            montant = Double.parseDouble( request.getParameter( "montantCommande" ) );
        } catch ( NumberFormatException e ) {
            /* Initialisation à -1 si le montant n'est pas un nombre correct */
            montant = -1;
        }
        String modePaiement = request.getParameter( "modePaiementCommande" );
        String statutPaiement = request.getParameter( "statutPaiementCommande" );
        String modeLivraison = request.getParameter( "modeLivraisonCommande" );
        String statutLivraison = request.getParameter( "statutLivraisonCommande" );

        String message;
        /*
         * Initialisation du message à afficher : si un des champs obligatoires
         * du formulaire n'est pas renseigné, alors on affiche un message
         * d'erreur, sinon on affiche un message de succès
         */
        if ( nom.trim().isEmpty() || adresse.trim().isEmpty() || telephone.trim().isEmpty() || montant == -1
                || modePaiement.isEmpty() || modeLivraison.isEmpty() ) {
            message = "Erreur - Vous n'avez pas rempli tous les champs obligatoires. <br> <a href=\"creerCommande.jsp\">Cliquez ici</a> pour accéder au formulaire de création d'une commande.";
        } else {
            message = "Commande créée avec succès !";
        }
        /*
         * Création des beans Client et Commande et initialisation avec les
         * données récupérées
         */
        Client client = new Client();
        client.setNom( nom );
        client.setPrenom( prenom );
        client.setAdresse( adresse );
        client.setTelephone( telephone );
        client.setEmail( email );

        Commande commande = new Commande();
        commande.setClient( client );
        commande.setDate( date );
        commande.setMontant( montant );
        commande.setModePaiement( modePaiement );
        commande.setStatutPaiement( statutPaiement );
        commande.setModeLivraison( modeLivraison );
        commande.setStatutLivraison( statutLivraison );

        /* Ajout du bean et du message à l'objet requête */
        request.setAttribute( "commande", commande );
        request.setAttribute( "message", message );

        /* Transmission à la page JSP en charge de l'affichage des données */
        this.getServletContext().getRequestDispatcher( "/afficherCommande.jsp" ).forward( request, response );
    }
}

Le code des JSP

Page d'affichage d'un client :

<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Affichage d'un client</title>
        <link type="text/css" rel="stylesheet" href="inc/style.css" />
    </head>
    <body>
        <%-- Affichage de la chaîne "message" transmise par la servlet --%>
        <p class="info">${ message }</p>
        <%-- Puis affichage des données enregistrées dans le bean "client" transmis par la servlet --%>
        <p>Nom : ${ client.nom }</p>
        <p>Prénom : ${ client.prenom }</p>
        <p>Adresse : ${ client.adresse }</p>
        <p>Numéro de téléphone : ${ client.telephone }</p>
        <p>Email : ${ client.email }</p>
    </body>
</html>

Page d'affichage d'une commande :

<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Affichage d'une commande</title>
        <link type="text/css" rel="stylesheet" href="inc/style.css" />
    </head>
    <body>
        <%-- Affichage de la chaîne "message" transmise par la servlet --%>
        <p class="info">${ message }</p>
        <%-- Puis affichage des données enregistrées dans le bean "commande" transmis par la servlet --%>
        <p>Client</p>
        <%-- Les 5 expressions suivantes accèdent aux propriétés du client, qui est lui-même une propriété du bean commande --%>
        <p>Nom : ${ commande.client.nom }</p>
        <p>Prénom : ${ commande.client.prenom }</p>
        <p>Adresse : ${ commande.client.adresse }</p>
        <p>Numéro de téléphone : ${ commande.client.telephone }</p>
        <p>Email : ${ commande.client.email }</p>
        <p>Commande</p>
        <p>Date  : ${ commande.date }</p> 
        <p>Montant  : ${ commande.montant }</p> 
        <p>Mode de paiement  : ${ commande.modePaiement }</p> 
        <p>Statut du paiement  : ${ commande.statutPaiement }</p> 
        <p>Mode de livraison  : ${ commande.modeLivraison }</p> 
        <p>Statut de la livraison  : ${ commande.statutLivraison }</p> 
    </body>
</html>

Encore une fois, prenez votre temps, lisez bien et analysez attentivement les codes. Ils vous serviront de base pour les prochaines étapes du fil rouge !

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