Après une brève introduction sur quelques concepts intervenant dans la suite de ce cours, et sur les versions de la JSTL, vous allez découvrir ici les fichiers de configuration clés de votre projet ainsi que les paramètres importants à modifier pour mettre en place la bibliothèque dans votre projet web Java EE.
C'est sa raison d'être… ♫
La JSTL est une bibliothèque, une collection regroupant des balises implémentant des fonctionnalités à des fins générales, communes aux applications web. Citons par exemple la mise en place de boucles, de tests conditionnels, le formatage des données ou encore la manipulation de données XML. Son objectif est de permettre au développeur d'éviter l'utilisation de code Java dans les pages JSP, et ainsi de respecter au mieux le découpage en couches recommandé par le modèle MVC. En apparence, ces balises ressemblent comme deux gouttes d'eau aux balises JSP que vous avez découvertes dans les chapitres précédents !
La liste d'avantages que je vous présente ci-dessous n'est probablement pas exhaustive. Je vais tenter de vous faire comprendre l'intérêt de l'utilisation des balises en vous exposant les aspects positifs qui me semblent les plus importants, et vous illustrer pourquoi l'utilisation de code Java dans vos pages JSP est déconseillée.
Lisibilité du code produit
Un des gros avantages de l'utilisation des balises JSTL, c'est sans aucun doute la lisibilité du code, et donc sa maintenabilité. Un exemple étant bien plus parlant que des mots, voici une simple boucle dans une JSP, d'abord en Java (à base de scriptlet donc), puis via des balises JSTL. Ne vous inquiétez pas de voir apparaître des notations qui vous sont, pour le moment, inconnues : les explications viendront par la suite.
Une boucle avec une scriptlet Java
1 2 3 4 5 6 7 | <%@ page import="java.util.List, java.util.ArrayList" %> <% List<Integer> list = (ArrayList<Integer>)request.getAttribute("tirage"); for(int i = 0; i < list.size();i++){ out.println(list.get(i)); } %> |
Pas besoin de vous faire un dessin : c'est du Java…
La même boucle avec des tags JSTL
1 2 3 | <c:forEach var="item" items="${tirage}" > <c:out value="${item}" /> </c:forEach> |
La boucle ainsi réalisée est nettement plus lisible ; elle ne fait plus intervenir d'attributs et de méthodes Java comme size()
, get()
ou encore des déclarations de variable, ni de types d'objets (List, ArrayList, Date, etc.), mais uniquement des balises à la syntaxe proche du XML qui ne gênent absolument pas la lecture du code et de la structure de la page.
Pour information, mais vous le saurez bien assez tôt, la bibliothèque de balises (on parle souvent de tags) ici utilisée, indiquée par le préfixe c:
, est la bibliothèque Core, que vous découvrirez dans le chapitre suivant.
Moins de code à écrire
Un autre gros avantage de l'utilisation des balises issues des bibliothèques standard est la réduction de la quantité de code à écrire. En effet, moins vous aurez à écrire de code, moins vous serez susceptibles d'introduire des erreurs dans vos pages. La syntaxe de nombreuses actions est simplifiée et raccourcie en utilisant la JSTL, ce qui permet d'éviter les problèmes dus à des fautes de frappe ou d'inattention dans des scripts en Java.
En outre, l'usage des scriptlets (le code Java entouré de <% %>
) est fortement déconseillé, et ce depuis l'apparition des TagLibs (notamment la JSTL) et des EL, soit depuis une dizaine d'années maintenant. Les principaux inconvénients des scriptlets sont les suivants :
- Réutilisation : il est impossible de réutiliser une scriptlet dans une autre page, il faut la dupliquer. Cela signifie que lorsque vous avez besoin d'effectuer le même traitement dans une autre page JSP, vous n'avez pas d'autre choix que de recopier le morceau de code dans l'autre page, et ce pour chaque page nécessitant ce bout de code. La duplication de code dans une application est, bien entendu, l'ennemi du bien : cela compromet énormément la maintenance de l'application.
- Interface : il est impossible de rendre une scriptlet
abstract
. - POO : il est impossible dans une scriptlet de tirer parti de l'héritage ou de la composition.
- Debug : si une scriptlet envoie une exception en cours d'exécution, tout s'arrête et l'utilisateur récupère une page blanche…
- Tests : on ne peut pas écrire de tests unitaires pour tester les scriptlets. Lorsqu'un développeur travaille sur une application relativement large, il doit s'assurer que ses modifications n'impactent pas le code existant et utilise pour cela une batterie de tests dits "unitaires", qui ont pour objectif de vérifier le fonctionnement des différentes méthodes implémentées. Eh bien ceux-ci ne peuvent pas s'appliquer au code Java écrit dans une page JSP : là encore, cela compromet énormément la maintenance et l'évolutivité de l'application.
- Maintenance : inéluctablement, il faut passer énormément plus de temps à maintenir un code mélangé, encombré, dupliqué et non testable !
À titre informatif, la maison mère Oracle elle-même recommande dans ses JSP coding conventions d'éviter l'utilisation de code Java dans une JSP autant que possible, notamment via l'utilisation de balises :
Vous avez dit MVC ?
Ne plus écrire de Java directement dans vos JSP
Vous l'avez probablement remarqué dans les exemples précédents : le Java complique énormément la lecture d'une page JSP. Certes, ici je ne vous ai présenté qu'une gentille petite boucle, donc la différence n'est pas si flagrante. Mais imaginez que vous travailliez sur un projet de plus grande envergure, mettant en jeu des pages HTML avec un contenu autrement plus riche, voire sur un projet dans le cadre duquel vous n'êtes pas l'auteur des pages que vous avez à maintenir ou à modifier : que préféreriez-vous manipuler ? Sans aucune hésitation, lorsque les balises JSTL sont utilisées, la taille des pages est fortement réduite. La compréhension et la maintenance s'en retrouvent grandement facilitées.
Rendre à la vue son vrai rôle
Soyez bien conscients d'une chose : je ne vous demande pas de proscrire le Java de vos pages JSP juste pour le plaisir des yeux !
Si je vous encourage à procéder ainsi, c'est pour vous faire prendre de bonnes habitudes : la vue, en l'occurrence nos JSP, ne doit se consacrer qu'à l'affichage. Ne pas avoir à déclarer de méthodes dans une JSP, ne pas modifier directement des données depuis une JSP, ne pas y insérer de traitement métier… tout cela est recommandé, mais la frontière peut paraître bien mince si on se laisse aller à utiliser des scriptlets Java dès que l'occasion se présente. Avec les tags JSTL, la séparation est bien plus nette.
Un autre point positif, qui ne vous concerne pas vraiment si vous ne travaillez pas en entreprise sur des projets de grande envergure, est que le modèle MVC permet une meilleure séparation des couches de l'application. Par exemple, imaginez une application dont le code Java est bien caché dans la couche métier (au hasard, dans des beans) : le(s) programmeur(s) UI très performant(s) en interface utilisateur peu(ven)t donc se baser sur la simple documentation du code métier pour travailler sur la couche de présentation en créant les vues, les JSP donc, et ce sans avoir à écrire ni lire de Java, langage qu'ils ne maîtrisent pas aussi bien, voire pas du tout.
À retenir
Si vous ne deviez retenir qu'une phrase de tout cela, c'est que bafouer MVC en écrivant du code Java directement dans une JSP rend la maintenance d'une application extrêmement compliquée, et par conséquent réduit fortement son évolutivité. Libre à vous par conséquent de décider de l'avenir que vous souhaitez donner à votre projet, en suivant ou non les recommandations.
Dernière couche : on écrit du code Java directement dans une JSP uniquement lorsqu'il nous est impossible de faire autrement, ou lorsque l'on désire vérifier un fonctionnement via une simple feuille de tests ; et enfin pourquoi pas lorsque l'on souhaite rapidement écrire un prototype temporaire afin de se donner une idée du fonctionnement d'une application de très faible envergure. Voilà, j'espère que maintenant vous l'avez bien assimilé, ce n'est pas faute de vous l'avoir répété…
Plusieurs versions
La JSTL a fait l'objet de plusieurs versions :
- JSTL 1.0 pour la plate-forme J2EE 3, et un conteneur JSP 1.2 (ex: Tomcat 4) ;
- JSTL 1.1 pour la plate-forme J2EE 4, et un conteneur JSP 2.0 (ex: Tomcat 5.5) ;
- JSTL 1.2, qui est partie intégrante de la plate-forme Java EE 6, avec un conteneur JSP 2.1 ou 3.0 (ex: Tomcat 6 et 7).
Les différences entre ces versions résident principalement dans le conteneur JSP nécessaire. Le changement majeur à retenir dans le passage de la première version à la seconde version de ce conteneur, c'est la gestion de la technologie EL. Le conteneur JSP 1.2 sur lequel est basée la JSTL 1.0 ne gérait pas les expressions EL, cette dernière proposait donc deux implémentations pour pallier ce manque : une les interprétant et l'autre non. Ceci se traduisait alors par l'utilisation d'adresses différentes lors de la déclaration des bibliothèques, nous allons revenir sur cela un petit peu plus loin.
La version 1.1 est basée sur le conteneur JSP 2.0, qui intègre nativement un interpréteur d'expressions EL, et ne propose par conséquent plus qu'une seule implémentation.
Ce tutoriel se base quant à lui sur la version actuelle, à savoir la JSTL 1.2, qui d'après le site officiel apporte des EL "unifiées", ainsi qu'une meilleure intégration dans le framework JSF. Ces changements par rapport à la précédente version n'ont aucun impact sur ce cours : tout ce qui suit sera valable, que vous souhaitiez utiliser la version 1.1 ou 1.2 de la JSTL.
Configuration
Configuration de la JSTL
Il y a plusieurs choses que vous devez savoir ici. Plutôt que de vous donner tout de suite les solutions aux problèmes qui vous attendent, fonçons têtes baissées, et je vous guiderai lorsque cela s’avérera nécessaire. On apprend toujours mieux en faisant des erreurs et en apprenant à les corriger, qu'en suivant bêtement une série de manipulations.
D'erreur en erreur…
Allons-y gaiement donc, et tentons naïvement d'insérer une balise JSTL ni vu ni connu dans notre belle et vierge page JSP :
1 2 3 4 5 6 7 8 9 | <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Test</title> </head> <body> <c:out value="test" /> </body> </html> |
Une balise JSTL dans notre page
Pour le moment, cette notation vous est inconnue, nous y reviendrons en temps voulu. Vous pouvez d'ores et déjà constater que cette balise a une syntaxe très similaire à celle des actions standard JSP. Pour votre information seulement, il s'agit ici d'un tag JSTL issu de la bibliothèque Core, permettant d'afficher du texte dans une page. Relativement basique donc…
Basique, sur le principe, oui. Mais Eclipse vous signale alors une première erreur (voir la figure suivante).
Il ne connaît visiblement pas cette balise. Et pour cause : puisqu'il est issu d'une bibliothèque (la JSTL), il est nécessaire de préciser à Eclipse où ce tag est réellement défini ! Et si vous avez suivi la partie précédente de ce cours, vous devez vous souvenir d'une certaine directive JSP, destinée à inclure des bibliothèques… Ça vous revient en mémoire ? Tout juste, c'est la directive taglib que nous allons utiliser ici. Voici donc notre code modifié pour inclure la bibliothèque Core :
1 2 3 4 5 6 7 8 9 10 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Test</title> </head> <body> <c:out value="test" /> </body> </html> |
Ajout de la directive taglib
Étudions cette directive :
- dans le paramètre uri se trouve le lien vers la définition de la bibliothèque. Remarquez bien ici l'arborescence de ce lien : /jsp/jstl/core. Si vous travaillez sur des codes qui ne sont pas de vous, vous serez éventuellement amenés à rencontrer dans cette balise un lien de la forme /jstl/core. Sachez que ce type de lien est celui de la version antérieure 1.0 de la JSTL. En effet, le dossier jsp a été rajouté afin d'éviter toute ambiguïté avec les précédentes versions qui, comme je vous l'ai précisé en première partie, ne géraient pas les EL. Faites bien attention à utiliser le bon lien selon la version de la JSTL que vous souhaitez utiliser, sous peine de vous retrouver avec des erreurs peu compréhensibles…
- dans le paramètre prefix se trouve l'alias qui sera utilisé dans notre page JSP pour faire appel aux balises de la bibliothèque en question. Concrètement, cela signifie que si je souhaite appeler le tag if de la bibliothèque Core, je dois écrire
<c:if>
. Si j'avais entré "core" dans le champ prefix de la directive au lieu de "c", j'aurais alors dû écrire<core:if>
.
Là, je suppose que vous vous apprêtez à me jeter des bûches. En effet, s'il est vrai qu'Eclipse vous signalait une alerte auparavant, vous vous retrouvez maintenant avec une nouvelle erreur en plus de la précédente (voir la figure suivante) !
Effectivement, nouvelle erreur. Pourquoi ?
Eh bien cette fois, c'est Tomcat qui est en cause ! Lorsque je vous avais présenté Tomcat, je vous avais bien précisé qu'il n'était pas un serveur d'applications Java EE au sens complet du terme. Nous voilà devant une première illustration de cet état de fait : alors que la JSTL fait partie intégrante de la plate-forme Java EE 6, Tomcat 7 n'est pas, par défaut, livré avec la JSTL. Si vous utilisez par exemple le serveur Glassfish d'Oracle, qui quant à lui respecte bien les spécifications Java EE, vous ne rencontrerez pas de problème : la JSTL y est bien incluse.
La lumière étant faite sur l'origine de cette erreur, il est temps de la corriger. Maintenant que nous avons précisé la définition de notre bibliothèque, il faut définir quelque part où se situe physiquement cette bibliothèque, et donc configurer notre projet afin qu'il puisse accéder à ses fichiers sources. Si vous êtes un peu curieux et que vous vous souvenez de ce que nous avons dû faire pour utiliser l'API JodaTime dans la partie précédente, vous avez probablement déjà remarqué que dans le dossier /WEB-INF de votre projet, il y a un dossier nommé… lib !
Le chemin semble donc tout tracé : nous devons aller chercher notre bibliothèque. Où la trouver ? J'y reviendrai dans le chapitre suivant, la JSTL contient nativement plusieurs bibliothèques, et Core est l'une d'entre elles. Par conséquent, c'est l'archive jar de la JSTL tout entière que nous allons devoir ajouter à notre projet. Vous pouvez télécharger le jar jstl-1.2.jar en cliquant sur ce lien de téléchargement direct. Vous voilà donc en possession du fichier que vous allez devoir copier dans votre répertoire lib, comme indiqué à la figure suivante.
Ça commence à bien faire, nous tournons en rond ! Nous avons inclus notre bibliothèque, mais nous avons toujours nos deux erreurs ! Que s'est-il passé ?
Pas d'inquiétude, nous apercevons le bout du tunnel… Effectivement, Eclipse vous crie toujours dessus. Mais ce n'est cette fois que pure illusion !
Note : je ne suis pas vraiment certain de la raison pour laquelle Eclipse ne met pas directement ses avertissements à jour. J'imagine que l'environnement a besoin d'une modification postérieure à la mise en place des bibliothèques pour prendre en compte complètement la modification. Bref, modifiez simplement votre page JSP, en y ajoutant un simple espace ou ce que vous voulez, et sauvez. Comme par magie, Eclipse cesse alors de vous crier dessus !
Il ne vous reste plus qu'à démarrer votre Tomcat si ce n'est pas déjà fait, et à vérifier que tout se passe bien, en accédant à votre JSP depuis votre navigateur via l'adresse http://localhost:8080/TestJSTL/test.jsp. Le mot "test" devrait alors s'afficher : félicitations, vous venez de mettre en place et utiliser avec succès votre premier tag JSTL !
- la JSTL est composée de cinq bibliothèques de balises standard ;
- elle permet d'éviter l'utilisation de code Java dans les pages JSP ;
- elle permet de réduire la quantité de code à écrire ;
- elle rend le code des pages JSP plus lisible ;
- sous Tomcat, il faut placer son fichier .jar sous /WEB-INF/lib pour qu'elle soit correctement intégrée.