Vous êtes sur la page 1sur 18

http://sites.google.

com/site/walidzeddini/cours

Programmation Web Avancée


Ch4- Thymeleaf

Walid ZEDDINI
Enseignant Expert J2EE – Institut supérieur d’Informatique (ISI)
Directeur de Projets IT- Tunisie TradeNet (TTN)

walid.zeddini@gmail.com
walid.zeddini@tradenet.com.tn

02/12/2019 © 2019 - 2020 - ISI - Tunis


02/12/2019
Outils et Framworks web
 Objectifs
 Permettre à l'étudiant de préparer et utiliser les outils et Frameworks nécessaire à la
programmation des application web.

 Contenu
 Qu’est ce que Thymeleaf
 Le dialecte SpringStandard
 Le formulaire:
• Gestion de l'objet de commande
• Input/entrée
Walid ZEDDINI, Programmation Web Avancée

• Checkbox fields / Champs de case à cocher


• Radio Button fields / Champs du bouton radio
• Dropdown/List selectors: Sélection / liste déroulante
 Travaux Pratiques
 Ce cours comporte des séances obligatoires de travaux pratiques (TP),
 Préparation de l’environnement de développement: IDE, Serveur Web, SGBD…
 Création d’un Projet Java et d’un Projet Web Spring Boot avec Maven
 Intégration Bootstrap et Thymeleaf

 Préalables
 Programmation Orientée Objet (Java)
 Initiation aux Technologies Web (Html / Css / JavaScript)
 Technologies internet 2
02/12/2019
Préface
 NOTA

 Il est important de noter que Thymeleaf possède des intégrations pour les versions
3.x et 4.x du Framework Spring, fournies par deux bibliothèques distinctes appelées
thymeleaf-spring3 et thymeleaf-spring4.

 Ces bibliothèques sont regroupées dans des fichiers .jar distincts (thymeleaf-
spring3- {version} .jar et thymeleaf-spring4- {version} .jar) et doivent être ajoutées à
votre chemin de classe (classpath) pour pouvoir utiliser les intégrations Spring de
Thymeleaf dans votre application.
Walid ZEDDINI, Programmation Web Avancée

 Les exemples de code de ce chapitre utilisent Spring 4.x et ses intégrations


Thymeleaf correspondantes, mais le contenu de ce chapitre est également valable
pour Spring 3.x.
 Si votre application utilise Spring 3.x, il vous suffit de remplacer le package
org.thymeleaf.spring4 par org.thymeleaf.spring3 dans les exemples de code.

 Ce chapitre explique comment Thymeleaf peut être intégré au Framework Spring,


en particulier (mais pas uniquement) Spring MVC.

3
02/12/2019
Qu’est ce que Thymeleaf
 Thymeleaf propose un ensemble d’intégrations Spring qui vous permettent de
l’utiliser comme substitut complet du logiciel JSP dans les applications Spring MVC.

 Ces intégrations vous permettront de:

 Transférer les méthodes mappées de vos objets Spring MVC @Controller vers
les modèles gérés par Thymeleaf, exactement comme vous le faites avec les
JSP.

 Utilisez Spring Expression Language (Spring EL) au lieu de OGNL dans vos
Walid ZEDDINI, Programmation Web Avancée

modèles.

 Créer des formulaires dans vos modèles qui soient complètement intégrés à
vos beans de sauvegarde de formulaire et à vos liaisons de résultats, y compris
l'utilisation d'éditeurs de propriétés, de services de conversion et du
traitement des erreurs de validation.

 Afficher les messages d'internationalisation des fichiers de messages gérés par


Spring (via les objets MessageSource habituels).

 Notez que pour bien comprendre ce chapitre, vous devez d'abord avoir suivi les
chapitres précédents relatives au Framework Spring.
4
Spring
Le dialecte SpringStandard
 Afin de réaliser une meilleure intégration et plus facile, Thymeleaf fournit un dialecte qui
implémente spécifiquement toutes les fonctionnalités nécessaires pour fonctionner
correctement avec Spring.

 Ce dialecte spécifique est basé sur le dialecte standard Thymeleaf et est implémenté
dans une classe appelée org.thymeleaf.spring4.dialect.SpringStandardDialect, qui
Walid ZEDDINI, Programmation Web Avancée

s'étend en fait de org.thymeleaf.standard.StandardDialect.

 Outre toutes les fonctionnalités déjà présentes dans le dialecte standard - et donc
héritées -, le dialect SpringStandard introduit les fonctionnalités spécifiques suivantes:
 Utilisez Spring Expression Language (Spring EL) comme langage d’expression
variable au lieu de OGNL. Par conséquent, toutes les expressions $ {...} et * {...}
seront évaluées par le moteur de Spring Expression Language.

 Accédez aux beans de votre contexte d’application à l’aide de la syntaxe


SpringEL: $ {@ myBean.doSomething ()}
02/12/2019 6
Le dialecte SpringStandard
 Nouveaux attributs pour le traitement de formulaire:
• th:field
• th: erreurs
• th: errorclass
 outre une nouvelle implémentation de th: object qui lui permet d'être utilisé pour
la sélection de commande de formulaire.
Walid ZEDDINI, Programmation Web Avancée

 Un objet et une méthode d'expression, # themes.code (...), qui équivaut à la


balise personnalisée JSP spring: theme.

 Un objet et une méthode d'expression, # mvc.uri (...), qui équivaut à la fonction


personnalisée JSP spring: mvcUrl (...) (uniquement dans Spring 4.1+).

 Nouvelles DTD pour la validation, y compris ces nouveaux attributs, ainsi que les
nouvelles règles de traduction DOCTYPE correspondantes.

02/12/2019 7
Le formulaire
 Gestion de l'objet de commande
 L'objet de commande est le nom que Spring MVC donne aux beans de sauvegarde de
formulaire ( form-backing beans):
Walid ZEDDINI, Programmation Web Avancée

 C'est-à-dire aux objets qui modélisent les champs d'un formulaire et fournissent des
méthodes de lecture et de définition (getter et setter) qui seront utilisées par le framework
pour établir et obtenir les valeurs saisies par l'utilisateur dans le navigateur.

 Thymeleaf exige que vous spécifiiez l'objet de commande en utilisant un attribut


th:object dans votre balise <form> :

<form action="#" th:action="@{/produit/save}" th:object="${produitForm}"


method="post">
...
</form>

02/12/2019 8
Le formulaire
 Gestion de l'objet de commande
 Ceci est cohérent avec d’autres utilisations de th: object,

 Mais en fait, ce scénario spécifique ajoute quelques limitations afin de s’intégrer


Walid ZEDDINI, Programmation Web Avancée

correctement à l’infrastructure de Spring MVC:

 Les valeurs pour les attributs th: object dans les balises de formulaire doivent
être des expressions variables ($ {...}) spécifiant uniquement le nom d'un
attribut de modèle, sans navigation de propriété. Cela signifie qu'une expression
comme $ {produitForm} est valide, mais que $ {produitForm.puProduit} ne le
serait pas.
 Une fois dans la balise <form>, aucun autre attribut th: object ne peut être
spécifié. Cela est cohérent avec le fait que les formulaires HTML ne peuvent
pas être imbriqués.
02/12/2019 9
Le formulaire
 Input/entrée
 Voyons maintenant comment ajouter une entrée à notre formulaire:

<input type="text" th:field="*{puProduit}" />


Walid ZEDDINI, Programmation Web Avancée

 Comme vous pouvez le constater, nous introduisons ici un nouvel attribut th:field. Il
s’agit d’une fonctionnalité très importante pour l’intégration de Spring MVC, car elle
permet de lier votre entrée à une propriété du bean de sauvegarde de formulaire.
 Vous pouvez le voir comme un équivalent de l’attribut path dans une balise de la
bibliothèque de balises JSP de Spring MVC.
 L'attribut th:field se comporte différemment selon qu'il est associé à une balise
<input>, <select> ou <textarea> (et également en fonction du type spécifique de
balise <input>).

<input type="text" id="puProduit" name="puProduit" th:value="*{puProduit}" />

02/12/2019 10
Le formulaire
 Input / entrée
<input type="text" id="puProduit" name="puProduit" th:value="*{puProduit}" />

 Les valeurs des attributs th:field doivent être des expressions de sélection * {...}
Walid ZEDDINI, Programmation Web Avancée

 Ce qui est logique étant donné qu'elles seront évaluées sur le bean de sauvegarde de
formulaire et non sur les variables de contexte (ou les attributs de modèle dans le
jargon Spring MVC).
 Contrairement à celles de th:object , ces expressions peuvent inclure la navigation
dans les propriétés (toute expression autorisée pour l'attribut path d'une balise JSP
<form: input> sera autorisée ici).

 Notez que th:field comprend également les nouveaux types d’élément <input>
introduits par HTML5, tels que <input type = "datetime" ... />, <input type = "color"
... />, etc., ajoutant effectivement compléter le support HTML5 pour Spring MVC.
02/12/2019 11
Le formulaire
 Checkbox fields / Champs de case à cocher
 Le th:field nous permet également de définir les entrées de case à cocher.
 Voyons un exemple :

<div>
<label th:for="${#ids.next('covered')}" th:text="#{seedstarter.covered}">Covered</label>
Walid ZEDDINI, Programmation Web Avancée

<input type="checkbox" th:field="*{covered}" />


</div>
 Notez qu’il y a quelques détails intéressants ici, en plus de la case à cocher elle-même,
comme une étiquette externalisée et l’utilisation de la fonction # ids.next ('covered')
pour obtenir la valeur qui sera appliquée à l’attribut id de l’entrée de la case à cocher.
 Pourquoi avons-nous besoin de cette génération dynamique d'un attribut id pour ce
champ? Comme les cases à cocher sont potentiellement multi-valeurs, leurs valeurs id
seront toujours complétées par un numéro de séquence (en utilisant en interne la
fonction # ids.seq (...)) afin de garantir que chacune des entrées de la case à cocher
pour la même propriété a une valeur d'identifiant différente.
02/12/2019 12
Le formulaire
 Checkbox fields / Champs de case à cocher
 Nous pouvons le voir plus facilement si nous examinons un tel champ de case à cocher
à plusieurs valeurs:

<ul>
<li th:each="feat : ${allFeatures}">
<input type="checkbox" th:field="*{features}" th:value="${feat}" />
<label th:for="${#ids.prev('features')}" th:text="#{${'seedstarter.feature.' + feat}}">Heating</label>
</li>
</ul>

 Notez que nous avons ajouté un attribut th:value cette fois-ci, car le champ features
n’est pas un booléen comme le fut covered, mais plutôt un tableau de valeurs.

 Voyons la sortie HTML générée par ce code:


02/12/2019 13
Le formulaire
 Checkbox fields / Champs de case à cocher
<ul>
<li>
<input id="features1" name="features" type="checkbox" value="SEEDSTARTER_SPECIFIC_SUBSTRATE" />
<input name="_features" type="hidden" value="on" /> <label for="features1">Seed starter-specific substrate</label>
</li>
<li>
<input id="features2" name="features" type="checkbox" value="FERTILIZER" />
<input name="_features" type="hidden" value="on" /> <label for="features2">Fertilizer used</label>
</li>
<li>
<input id="features3" name="features" type="checkbox" value="PH_CORRECTOR" />
<input name="_features" type="hidden" value="on" />
<label for="features3">PH Corrector used</label>
</li>
</ul>

 Nous pouvons voir ici comment un suffixe de séquence est ajouté à l’attribut id de
chaque entrée et comment la fonction # ids.prev (...) nous permet de récupérer la
dernière valeur de séquence générée pour un identifiant d’entrée spécifique.

02/12/2019 14
Le formulaire
 Checkbox fields / Champs de case à cocher
 Ne vous inquiétez pas des entrées masquées avec name ="_features" : elles sont
automatiquement ajoutées afin d'éviter des problèmes avec les navigateurs n'envoyant
pas de valeurs de case à cocher non cochées au serveur lors de la soumission du
formulaire.

 Notez également que si notre propriété features contenait certaines valeurs


sélectionnées dans notre bean de sauvegarde de formulaire, th: field s'en serait

occupé et aurait ajouté un attribut checked="checked" aux balises d'entrée


correspondantes.

02/12/2019 15
Le formulaire
 Radio Button fields / Champs du bouton radio
 Les champs de boutons radio sont spécifiés d'une manière similaire aux cases à cocher
non booléennes (à valeurs multiples) - à l'exception du fait qu'elles ne sont pas à
valeurs multiples, bien sûr:

<ul>
<li th:each="ty : ${allTypes}"> <input type="radio" th:field="*{type}" th:value="${ty}" />
<label th:for="${#ids.prev('type')}" th:text="#{${'seedstarter.type.' + ty}}">Wireframe</label>
</li>
</ul>

02/12/2019 16
Le formulaire
 Dropdown/List selectors: Sélection / liste déroulante
 Les champs de sélection comportent deux parties: la balise <select> et ses balises
<option> imbriquées.
 Lors de la création de ce type de champ, seule la balise <select> doit inclure un attribut
th:field, mais les attributs th:value des balises <option> imbriquées seront très
importants car ils permettront de connaître le type de champ (option) actuellement
sélectionnée (de la même manière que les cases à cocher et les boutons radio non
booléens).
 Exemple:

<select th:field="*{type}">
<option th:each="type : ${allTypes}" th:value="${type}" th:text="#{${'seedstarter.type.' + type}}">
Wireframe</option>
</select>

 À ce stade, il est assez facile de comprendre ce code. Il suffit de remarquer que la


priorité des attributs nous permet de définir l'attribut th:each dans la balise <option>
elle-même. 17
02/12/2019
Webographie
 https://www.thymeleaf.org/
 https://spring.io
Walid ZEDDINI, Programmation Web Avancée

18