IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

 

Développons en Java   2.30  
Copyright (C) 1999-2022 Jean-Michel DOUDOUX    (date de publication : 15/06/2022)

[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

 

78. Les JSP (Java Server Pages)

 

chapitre    7 8

 

Niveau : niveau 4 Supérieur 

 

Les JSP (Java Server Pages) sont une technologie Java qui permet la génération de pages web dynamiques.

La technologie JSP permet de séparer la présentation sous forme de code HTML et les traitements écrits en Java sous la forme de JavaBeans ou de servlets. Ceci est d'autant plus facile que les JSP définissent une syntaxe particulière permettant d'appeler un bean et d'insérer le résultat de son traitement dans la page HTML dynamiquement.

Les informations fournies dans ce chapitre concernent les spécifications 1.0 et ultérieures des JSP.

Ce chapitre contient plusieurs sections :

 

78.1. La présentation des JSP

Les JSP permettent d'introduire du code Java dans des tags prédéfinis à l'intérieur d'une page HTML. La technologie JSP mélange la puissance de Java côté serveur et la facilité de mise en page d'HTML côté client.

La page officielle de cette technologie est à l'adresse suivante :
https://www.oracle.com/java/technologies/jspt.html.

Une JSP est habituellement constituée :

  • de données et de tags HTML
  • de tags JSP
  • de scriptlets (code Java intégré à la JSP)

Les fichiers JSP possèdent par convention l'extension .jsp.

Concrètement, les JSP sont basées sur les servlets. Au premier appel de la page JSP, le moteur de JSP génère et compile automatiquement la servlet qui permet la génération de la page web. Le code HTML est repris intégralement dans la servlet. Le code Java est inséré dans la servlet.

La servlet générée est compilée et sauvegardée puis elle est exécutée. Les appels suivants de la JSP sont beaucoup plus rapides car la servlet, conservée par le serveur, est directement exécutée.

Il y a plusieurs manières de combiner les technologies JSP, les beans/EJB et les servlets en fonction des besoins pour développer des applications web.

Comme le code de la servlet est généré dynamiquement, les JSP sont relativement difficiles à déboguer.

Cette approche présente cependant plusieurs avantages :

  • l'utilisation de Java par les JSP permet une indépendance de la plate-forme d'exécution mais aussi du serveur web utilisé.
  • la séparation des traitements et de la présentation : la page web peut être écrite par un designer et les tags Java peuvent être ajoutés ensuite par le développeur. Les traitements peuvent être réalisés par des composants réutilisables (des Java beans).
  • les JSP sont basées sur les servlets : tout ce qui est fait par une servlet pour la génération de pages dynamiques peut être fait avec une JSP.

Il existe plusieurs versions des spécifications JSP :

Version  
0.91 Première release
1.0

Juin 1999 : première version finale
lié à l'API servlet 2.1

1.1 Décembre 1999
lié à l'API servlet 2.2
1.2 Octobre 2000, JSR 053
lié à l'API servlet 2.3
2.0 Novembre 2003, JSR 152
lié à l'API servlet 2.4
2.1 Mai 2006, JSR 245
lié à l'API servlet 2.5
2.2 Décembre 2009, Maintenance release de la JSR 245
lié à l'API servlet 3.0
2.3 Juin 2013, Maintenance release de la JSR 245
lié à l'API servlet 3.1

 

78.1.1. Le choix entre JSP et Servlets

Les servlets et les JSP ont de nombreux points communs puisqu'une JSP est finalement convertie en une servlet. Le choix d'utiliser l'une ou l'autre de ces technologies ou les deux doit être fait pour tirer le meilleur parti de leurs avantages.

Dans une servlet, les traitements et la présentation sont regroupés. L'aspect présentation est dans ce cas pénible à développer et à maintenir à cause de l'utilisation répétitive de méthodes pour insérer le code HTML dans le flux de sortie. De plus, une simple petite modification dans le code HTML nécessite la recompilation de la servlet. Avec une JSP, la séparation des traitements et de la présentation rend ceci très facile et automatique.

Il est préférable d'utiliser les JSP pour générer des pages web dynamiques.

L'usage des servlets est obligatoire si celles-ci doivent communiquer directement avec une applet ou une application et non plus avec un serveur web.

 

78.1.2. Les JSP et les technologies concurrentes

Il existe plusieurs technologies dont le but est similaire aux JSP notamment ASP, PHP et ASP.Net. Chacune de ces technologies possèdent des avantages et des inconvénients dont voici une liste non exhaustive.

 
JSP
PHP
ASP
ASP.Net
langage
Java
PHP
VBScript ou JScript
Tous les langages supportés par .Net (C#, VB.Net, Delphi, ...)
mode d'exécution
Compilé en pseudo code (bytecode)
Interprété
Interprété
Compilé en pseudo code (MSIL)
principaux avantages Repose sur la plate-forme Java dont elle hérite des avantages Open source
Nombreuses bibliothèques et sources d'applications libres disponibles
Facile à mettre en oeuvre
Facile à mettre en oeuvre Repose sur la plate-forme .Net dont elle hérite des avantages
Wysiwyg et événementiel
Code behind pour séparation affichage / traitements
principaux inconvénients Débogage assez fastidieux
Beaucoup de code à écrire
Débogage assez fastidieux
Beaucoup de code à écrire
support partiel de la POO en attendant la version 5
Débogage assez fastidieux
Beaucoup de code à écrire
Fonctionne essentiellement sur plates-formes Windows
Pas de POO, objets métiers encapsulés dans des objets COM lourds à mettre en oeuvre
Fonctionne essentiellement sur plates-formes Windows. (Voir le projet Mono pour le support d'autres plates-formes)

 

78.2. Les outils nécessaires

Dans un premier temps, Sun a fourni un kit de développement pour les JSP : le Java Server Web Development Kit (JSWDK). Ensuite, Sun a chargé le projet Apache de développer l'implémentation de référence du moteur de JSP : le projet Tomcat. Depuis la version 2.2, l'implémentation de référence est le projet Glassfish.

En fonction des versions des API utilisées, il faut choisir un produit différent. Le tableau ci-dessous résume les implémentations de référence en fonction de la version de l'API mise en oeuvre.

Produit
Version
Version de l'API servlet implémentée
Version de l'API JSP implémentée
JSWDK
1.0.1
2.1
1.0
Tomcat
3.2
2.2
1.1
Tomcat
4.0
2.3
1.2
Tomcat
5.0
2.4
2.0
Tomcat
6.0
2.5
2.1
Glassfish
3.0
3.0
2.2
Glassfish
4.0
3.1
2.3

Il est aussi possible d'utiliser n'importe quel conteneur web compatible avec les spécifications de la plate-forme J2EE/Java EE. Une liste non exhaustive est fournie dans le chapitre «Les outils libres et commerciaux».

 

78.2.1. L'outil JavaServer Web Development Kit (JSWDK) sous Windows

Le JSWDK est proposé sous la forme d'un fichier zip nommé jswdk_1_0_1-win.zip.

Pour l'installer, il suffit de décompresser l'archive dans un répertoire du système. Le serveur se lance en exécutant le fichier startserver.bat.

Pour lancer le serveur :
C:\jswdk-1.0.1>startserver.bat

Using classpath:.\classes;.\webserver.jar;.\lib\jakarta.jar;.\lib\servlet.jar;.
\lib\jsp.jar;.\lib\jspengine.jar;.\examples\WEB-INF\jsp\beans;.\webpages\WEB-INF
\servlets;.\webpages\WEB-INF\jsp\beans;.\lib\xml.jar;.\lib\moo.jar;\lib\tools.ja
r;C:\jdk1.3\lib\tools.jar;
C:\jswdk-1.0.1>

Le serveur s'exécute dans une console en tâche de fond. Cette console permet de voir les messages émis par le serveur.

Exemple : au démarrage
JSWDK WebServer Version 1.0.1
Loaded configuration from: file:C:\jswdk-1.0.1\webserver.xml
endpoint created: localhost/127.0.0.1:8080

Si la JSP contient une erreur, le serveur envoie une page d'erreur :

Une exception est levée et est affichée dans la fenêtre où le serveur s'exécute :

Exemple :
-- Commentaires de la page JSP --
^
1 error
at com.sun.jsp.compiler.Main.compile(Main.java:347)
at com.sun.jsp.runtime.JspLoader.loadJSP(JspLoader.java:135)
at com.sun.jsp.runtime.JspServlet$JspServletWrapper.loadIfNecessary(JspS
ervlet.java:77)
at com.sun.jsp.runtime.JspServlet$JspServletWrapper.service(JspServlet.j
ava:87)
at com.sun.jsp.runtime.JspServlet.serviceJspFile(JspServlet.java:218)
at com.sun.jsp.runtime.JspServlet.service(JspServlet.java:294)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:840)
at com.sun.web.core.ServletWrapper.handleRequest(ServletWrapper.java:155
) 
at com.sun.web.core.Context.handleRequest(Context.java:414)
at com.sun.web.server.ConnectionHandler.run(ConnectionHandler.java:139)
HANDLER THREAD PROBLEM: java.io.IOException: Socket Closed
java.io.IOException: Socket Closed
at java.net.PlainSocketImpl.getInputStream(Unknown Source)
at java.net.Socket$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.Socket.getInputStream(Unknown Source)
at com.sun.web.server.ConnectionHandler.run(ConnectionHandler.java:161)

Le répertoire work contient le code et le bytecode des servlets générées à partir des JSP.

Pour arrêter le serveur, il suffit d'exécuter le script stopserver.bat.

A l'arrêt du serveur, le répertoire work qui contient les servlets générées à partir des JSP est supprimé.

 

78.2.2. Le serveur Tomcat

La mise en oeuvre et l'utilisation de Tomcat est détaillée dans une section du chapitre «Les servlets».

 

78.3. Le code HTML

Une grande partie du contenu d'une JSP est constituée de code HTML. D'ailleurs, le plus simple pour écrire une JSP est d'écrire le fichier HTML avec un outil dédié et d'ajouter ensuite les tags JSP pour ce qui concerne les parties dynamiques.

La seule restriction concernant le code HTML concerne l'utilisation des fragments " <% " et " %> " dans la page générée. Dans ce cas, le plus simple est d'utiliser les caractères spéciaux HTML &lt; et &gt;. Sinon l'analyseur syntaxique du moteur de JSP considère que ce sont des tags JSP et renvoie une erreur.

Exemple :
<HTML>
<HEAD>
<TITLE>Test</TITLE>
</HEAD>
<BODY>
<p>Plusieurs tags JSP commencent par &lt;% et se finissent par %&gt;</p>
</BODY>
</HTML>

 

78.4. Les Tags JSP

Il existe trois types de tags :

  • tags de directives : ils permettent de contrôler la structure de la servlet générée
  • tags de scripting: ils permettent d'insérer du code Java dans la servlet
  • tags d'actions: ils facilitent l'utilisation de composants
stop Attention : Les noms des tags sont sensibles à la casse.

 

78.4.1. Les tags de directives <%@ ... %>

Les directives permettent de préciser des informations globales sur la page JSP. Les spécifications des JSP définissent trois directives :

  • page : permet de définir des options de configuration
  • include : permet d'inclure des fichiers statiques dans la JSP avant la génération de la servlet
  • taglib : permet de définir des tags personnalisés

Leur syntaxe est la suivante :

<%@ directive attribut="valeur" ... %>

 

78.4.1.1. La directive page

Cette directive doit être utilisée dans toutes les pages JSP : elle permet de définir des options qui s'appliquent à toute la JSP.

Elle peut être placée n'importe où dans le source mais il est préférable de la mettre en début de fichier, avant même le tag <HTML>. Elle peut être utilisée plusieurs fois dans une même page mais elle ne doit définir la valeur d'une option qu'une seule fois, sauf pour l'option import.

Les options définies par cette directive sont de la forme option=valeur.

Option
Valeur
Valeur par défaut
Autre valeur possible
autoFlush
Une chaîne
«true»
«false»
buffer
Une chaîne
«8kb»
«none» ou «nnnkb» (nnn indiquant la valeur)
contentType
Une chaîne contenant le type MIME
   
errorPage
Une chaîne contenant une URL
   
extends
Une classe
   
import
Une classe ou un package.*
   
info
Une chaîne
   
isErrorPage
Une chaîne
«false»
«true»
isThreadSafe
Une chaîne
«true»
«false»
langage
Une chaîne
«java»
 
session
Une chaîne
«true»
«false»

Exemple :
<%@ page import="java.util.*" %>
<%@ page import="java.util.Vector" %>
<%@ page info="Ma premiere JSP"%>

Les options sont :

  • autoFlush="true|false"

    Cette option indique si le flux en sortie de la servlet doit être vidé quand le tampon est plein. Si la valeur est false, une exception est levée dès que le tampon est plein. On ne peut pas mettre false si la valeur de buffer est none.

  • buffer="none|8kb|sizekb"

    Cette option permet de préciser la taille du buffer des données générées contenues par l'objet out de type JspWriter.

  • contentType="mimeType [ ; charset=characterSet ]" | "text/html;charset=ISO-8859-1"

    Cette option permet de préciser le type MIME des données générées.

    Cette option est équivalente à <% response.setContentType("mimeType"); %>

  • errorPage="relativeURL"

    Cette option permet de préciser la JSP appelée au cas où une exception est levée

    Si l'URL commence pas un '/', alors l'URL est relative au répertoire principale du serveur web sinon elle est relative au répertoire qui contient la JSP

  • extends="package.class"

    Cette option permet de préciser la classe qui sera la super classe de l'objet Java créé à partir de la JSP.

  • import= "{ package.class | package.* }, ..."

    Cette option permet d'importer des classes contenues dans des packages utilisées dans le code de la JSP. Cette option s'utilise comme l'instruction import dans un code source Java.

    Chaque classe ou package est séparée par une virgule.

    Cette option peut être présente dans plusieurs directives page.

  • info="text"

    Cette option permet de préciser un petit descriptif de la JSP. Le texte fourni sera renvoyé par la méthode getServletInfo() de la servlet générée.

  • isErrorPage="true|false"

    Cette option permet de préciser si la JSP génère une page d'erreur. La valeur true permet d'utiliser l'objet Exception dans la JSP

  • isThreadSafe="true|false"

    Cette option indique si la servlet générée sera multithread : dans ce cas, une même instance de la servlet peut gérer plusieurs requêtes simultanément. En contrepartie, elle doit gérer correctement les accès concurrents aux ressources. La valeur false impose à la servlet générée d'implémenter l'interface SingleThreadModel.

  • language="java"

    Cette option définit le langage utilisé pour écrire le code dans la JSP. La seule valeur autorisée actuellement est «java».

  • session="true|false"

    Cette option permet de préciser si la JSP est incluse dans une session ou non. La valeur par défaut (true) permet l'utilisation d'un objet session de type HttpSession qui permet de gérer des informations dans une session.

 

78.4.1.2. La directive include

Cette directive permet d'inclure un fichier dans le code source JSP. Le fichier inclus peut être un fragment de code JSP, HTML ou Java. Le fichier est inclus dans la JSP avant que celle-ci ne soit interprétée par le moteur de JSP.

Ce tag est particulièrement utile pour insérer un élément commun à plusieurs pages tel qu'un en-tête ou un bas de page.

Si le fichier inclus est un fichier HTML, celui-ci ne doit pas contenir de tag <HTML>, </HTML>, <BODY> ou </BODY> qui ferait double emploi avec ceux présents dans le fichier JSP. Ceci impose d'écrire des fichiers HTML particuliers uniquement pour être inclus dans les JSP : ils ne pourront pas être utilisés seuls.

La syntaxe est la suivante :

<%@ include file="chemin relatif du fichier" %>

Si le chemin commence par un '/', alors le chemin est relatif au contexte de l'application, sinon il est relatif au fichier JSP.

Exemple : bonjour.htm
<p><table border="1" cellpadding="4" cellspacing="0" width="30%" align=center >
<tr bgcolor="#A6A5C2">
<td align="center">BONJOUR</Td>
</Tr>
</table></p>
Exemple : Test1.jsp
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<p align="center">Test d'inclusion d'un fichier dans la JSP</p>
<%@ include file="bonjour.htm"%>
<p align="center">fin</p>
</BODY>
</HTML>

Pour tester cette JSP avec le JSWDK, il suffit de placer ces deux fichiers dans le répertoire jswdk-1.0.1\examples\jsp\test.

Pour visualiser la JSP, il faut saisir l'url http://localhost:8080/examples/jsp/test/Test1.jsp dans un navigateur.

stop Attention : un changement dans le fichier inclus ne provoque pas une regénération et une compilation de la servlet correspondant à la JSP. Pour insérer un fichier dynamiquement à l'exécution de la servlet il faut utiliser le tag <jsp:include>.

 

78.4.1.3. La directive taglib

Cette directive permet de déclarer l'utilisation d'une bibliothèque de tags personnalisés. L'utilisation de cette directive est détaillée dans la section consacrée aux bibliothèques de tags personnalisés.

 

78.4.2. Les tags de scripting

Ces tags permettent d'insérer du code Java qui sera inclus dans la servlet générée à partir de la JSP. Il existe trois tags pour insérer du code Java :

  • le tag de déclaration : le code Java est inclus dans le corps de la servlet générée. Ce code peut être la déclaration de variables d'instances ou de classes ou la déclaration de méthodes.
  • le tag d'expression : évalue une expression et insère le résultat sous forme de chaîne de caractères dans la page web générée.
  • le tag de scriptlets : par défaut, le code Java est inclus dans la méthode service() de la servlet.

Il est possible d'utiliser dans ces tags plusieurs objets définis par les JSP.

 

78.4.2.1. Le tag de déclarations <%! ... %>

Ce tag permet de déclarer des variables ou des méthodes qui pourront être utilisées dans la JSP. Il ne génère aucun caractère dans le fichier HTML de sortie.

La syntaxe est la suivante :

<%! declarations %>

Exemple :
<%! int i = 0; %> 
<%! dateDuJour = new java.util.Date(); %>

Les variables ainsi déclarées peuvent être utilisées dans les tags d'expressions et de scriptlets.

Il est possible de déclarer plusieurs variables dans le même tag en les séparant avec des caractères ' ;'.

Ce tag permet aussi d'insérer des méthodes dans le corps de la servlet.

Exemple :
<HTML>
<HEAD>
<TITLE>Test</TITLE>
</HEAD>
<BODY>
<%! 
int minimum(int val1, int val2) { 
   if (val1 < val2) return val1;
   else return val2;
} 
%> 
<% int petit = minimum(5,3);%>
<p>Le plus petit de 5 et 3 est <%= petit %></p>
</BODY> 
</HTML>

 

78.4.2.2. Le tag d'expressions <%= ... %>

Le moteur de JSP remplace ce tag par le résultat de l'évaluation de l'expression présente dans le tag.

Ce résultat est toujours converti en une chaîne. Ce tag est un raccourci pour éviter de faire appel à la méthode println() lors de l'insertion de données dynamiques dans le fichier HTML.

La syntaxe est la suivante :

<%= expression %>

Le signe '=' doit être collé au signe '%'.

stop Attention : il ne faut pas mettre de ' ;' à la fin de l'expression.

Exemple : Insertion de la date dans la page HTML
<%@ page import="java.util.*" %>
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<p align="center">Date du jour : 
<%= new Date() %>
</p>
</BODY>
</HTML>
Résultat :
Date du jour : Thu Feb 15 11:15:24 CET 2001

L'expression est évaluée et convertie en chaîne avec un appel à la méthode toString(). Cette chaîne est insérée dans la page HTML en remplacement du tag. Il est ainsi possible que le résultat soit une partie ou la totalité d'un tag HTML ou même une JSP.

Exemple :
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<%="<H1>" %>Bonjour<%="</H1>" %>
</BODY>
</HTML>
Résultat : code HTML généré
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<H1>Bonjour</H1>
</BODY>
</HTML>

 

78.4.2.3. Les variables implicites

Les spécifications des JSP définissent plusieurs objets utilisables dans le code dont les plus utiles sont :

Object
Classe
Rôle
out
javax.servlet.jsp.JspWriter
Flux en sortie de la page HTML générée
request
javax.servlet.http.HttpServletRequest
Contient les informations de la requête
response
javax.servlet.http.HttpServletResponse
Contient les informations de la réponse
session
javax.servlet.http.HttpSession
Gère la session

 

78.4.2.4. Le tag des scriptlets <% ... %>

Ce tag contient du code Java nommé un scriptlet.

La syntaxe est la suivante : <% code Java %>

Exemple :
<%@ page import="java.util.Date"%>
<html>
<body>
<%! Date dateDuJour; %>
<% dateDuJour = new Date();%>
Date du jour : <%= dateDuJour %><BR>
</body>
</html>

Par défaut, le code inclus dans le tag est inséré dans la méthode service() de la servlet générée à partir de la JSP.

Ce tag ne peut pas contenir autre chose que du code Java : il ne peut pas par exemple contenir de tags HTML ou JSP. Pour faire cela, il faut fermer le tag du scriptlet, mettre le tag HTML ou JSP puis de nouveau commencer un tag de scriptlet pour continuer le code.

Exemple :
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<% for (int i=0; i<10; i++) { %> 
<%= i %> <br>
<% }%>
</BODY>
</HTML>
Résultat : la page HTML générée
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
0 <br>
1 <br>
2 <br>
3 <br>
4 <br>
5 <br>
6 <br>
7 <br>
8 <br>
9 <br>
</BODY>
</HTML>

 

78.4.3. Les tags de commentaires

Il existe deux types de commentaires avec les JSP :

  • les commentaires visibles dans le code HTML
  • les commentaires invisibles dans le code HTML

 

78.4.3.1. Les commentaires HTML <!-- ... -->

Ces commentaires sont ceux définis par le format HTML. Ils sont intégralement reproduits dans le fichier HTML généré. Il est possible d'insérer, dans ce tag, un tag JSP de type expression qui sera exécuté.

La syntaxe est la suivante :

<!-- commentaires [ <%= expression %> ] -->

Exemple :
<%@ page import="java.util.*" %>
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<!-- Cette page a ete generee le <%= new Date() %> -->
<p>Bonjour</p>
</BODY>
</HTML>
Résultat :
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<!-- Cette page a ete generee le Thu Feb 15 11:44:25 CET 2001 -->
<p>Bonjour</p>
</BODY>
</HTML>

Le contenu d'une expression incluse dans des commentaires est dynamique : sa valeur peut changer à chaque génération de la page en fonction de son contenu.

 

78.4.3.2. Les commentaires cachés <%-- ... --%>

Les commentaires cachés sont utilisés pour documenter la page JSP. Leur contenu est ignoré par le moteur de JSP et ne sont donc pas reproduits dans la page HTML générée.

La syntaxe est la suivante :

<%-- commentaires --%>

Exemple :
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<%-- Commentaires de la page JSP --%>
<p>Bonjour</p>
</BODY>
</HTML>
Résultat :
<HTML>
<HEAD>
<TITLE>Essai de page JSP</TITLE>
</HEAD>
<BODY>
<p>Bonjour</p>
</BODY>
</HTML>

Ce tag peut être utile pour éviter l'exécution de code lors de la phase de débogage.

 

78.4.4. Les tags d'actions

Les tags d'actions permettent de réaliser des traitements couramment utilisés.

 

78.4.4.1. Le tag <jsp:useBean>

Le tag <jsp:useBean> permet de localiser une instance ou d'instancier un bean pour l'utiliser dans la JSP.

L'utilisation d'un bean dans une JSP est très pratique car il peut encapsuler des traitements complexes et être réutilisable par d'autre JSP ou composants. Le bean peut par exemple assurer l'accès à une base de données. L'utilisation des beans permet de simplifier les traitements inclus dans la JSP.

Lors de l'instanciation d'un bean, on précise la portée du bean. Si le bean demandé est déjà instancié pour la portée précisée alors il n'y pas de nouvelle instance du bean qui est créée mais sa référence est simplement renvoyée : le tag <jsp:useBean> n'instancie donc pas obligatoirement un objet.

Ce tag ne permet pas de traiter directement des EJB.

La syntaxe est la suivante :

<jsp:useBean
id="beanInstanceName"
scope="page|request|session|application"
{ class="package.class" |
type="package.class" |
class="package.class" type="package.class" |
beanName="{package.class | <%= expression %>}" type="package.class"
}
{ /> |
> ...
</jsp:useBean>
}

L'attribut id permet de donner un nom à la variable qui va contenir la référence sur le bean.

L'attribut scope permet de définir la portée sur laquelle le bean est défini et utilisable. La valeur de cet attribut détermine la manière dont le tag localise ou instancie le bean. Les valeurs possibles sont :

Valeur Rôle
page Le bean est utilisable dans toute la page JSP ainsi que dans les fichiers statiques inclus. C'est la valeur par défaut.
request le bean est accessible durant la durée de vie de la requête. La méthode getAttribute() de l'objet request permet d'obtenir une référence sur le bean.
session le bean est utilisable par toutes les JSP qui appartiennent à la même session que la JSP qui a instanciée le bean. Le bean est utilisable tout au long de la session par toutes les pages qui y participent. La JSP qui crée le bean doit avoir l'attribut session = « true » dans sa directive page.
application le bean est utilisable par toutes les JSP qui appartiennent à la même application que la JSP qui a instanciée le bean. Le bean n'est instancié que lors du rechargement de l'application.

L'attribut class permet d'indiquer la classe du bean.

L'attribut type permet de préciser le type de la variable qui va contenir la référence du bean. La valeur indiquée doit obligatoirement être une super classe du bean ou une interface implémentée par le bean (directement ou par héritage).

L'attribut beanName permet d'instancier le bean grâce à la méthode instanciate() de la classe Beans.

Exemple :
<jsp:useBean id="monBean" scope="session" class="test.MonBean" />

Dans cet exemple, une instance de MonBean est créée une seule et unique fois lors de la session. Dans la même session, l'appel du tag <jsp:useBean> avec le même bean et la même portée ne feront que renvoyer l'instance créée. Le bean est ainsi accessible durant toute la session.

Le tag <jsp:useBean> recherche si une instance du bean existe avec le nom et la portée précisée. Si elle n'existe pas, alors une instance est créée. S'il y a instanciation du bean, alors les tags <jsp:setProperty> inclus dans le tag sont utilisés pour initialiser les propriétés du bean sinon ils sont ignorés. Les tags inclus entre les tags <jsp:useBean> et </jsp:useBean> ne sont exécutés que si le bean est instancié.

Exemple :
<jsp:useBean id="monBean" scope="session" class="test.MonBean" >
<jsp:setProperty name="monBean" property="*" />
</jsp:useBean>

Cet exemple a le même effet que le précédent avec une initialisation des propriétés du bean lors de son instanciation.

Exemple complet : TestBean.jsp
<html>
<HEAD>
<TITLE>Essai d'instanciation d'un bean dans une JSP</TITLE>
</HEAD>
<body>
<p>Test d'utilisation d'un Bean dans une JSP </p>
<jsp:useBean id="personne" scope="request" class="test.Personne" />
<p>nom initial = <%=personne.getNom() %></p>
<%personne.setNom("mon nom");%>
<p>nom mis à jour = <%= personne.getNom() %></p>
</body>
</html>
Exemple complet : Personne.java
package test;
	  
public class Personne {
  private String nom;
  private String prenom;
  
  public Personne() {
    this.nom = "nom par defaut";
    this.prenom = "prenom par defaut";
  }
  
  public void setNom (String nom) {
    this.nom = nom;
  }
  
  public String getNom() {
    return (this.nom);
  }

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

  public String getPrenom () {
    return (this.prenom);
  }
}

Selon le moteur de JSP utilisé, les fichiers du bean doivent être placés dans un répertoire particulier pour être accessibles par la JSP.

Pour tester cette JSP avec Tomcat, il faut compiler le bean Personne dans le répertoire c:\jakarta-tomcat\webapps\examples\web-inf\classes\test et placer le fichier TestBean.jsp dans le répertoire c:\jakarta-tomcat\webapps\examples\jsp\test.

 

78.4.4.2. Le tag <jsp:setProperty >

Le tag <jsp:setProperty> permet de mettre à jour la valeur d'un ou plusieurs attributs d'un Bean. Le tag utilise le setter (méthode setXXX() où XXX est le nom de la propriété avec la première lettre en majuscule) pour mettre à jour la valeur. Le bean doit exister grâce à un appel au tag <jsp:useBean>.

Il existe trois façons de mettre à jour les propriétés soit à partir des paramètres de la requête soit avec une valeur :

  • alimenter automatiquement toutes les propriétés avec les paramètres correspondants de la requête
  • alimenter automatiquement une propriété avec le paramètre de la requête correspondant
  • alimenter une propriété avec la valeur précisée

La syntaxe est la suivante :

<jsp:setProperty name="beanInstanceName"
{ property="*" |
property="propertyName" [ param=" parameterName" ] |
property="propertyName" value="{string | <%= expression%>}"
}
/>

L'attribut name doit contenir le nom de la variable qui contient la référence du bean. Cette valeur doit être identique à celle de l'attribut id du tag <jsp:useBean> utilisé pour instancier le bean.

L'attribut property= «*» permet d'alimenter automatiquement les propriétés du bean avec les paramètres correspondants contenus dans la requête. Le nom des propriétés et le nom des paramètres doivent être identiques.

Comme les paramètres de la requête sont toujours fournis sous forme de String, une conversion est réalisée en utilisant la méthode valueOf() du wrapper du type de la propriété.

Exemple :
<jsp:setProperty name="monBean" property="*" />

L'attribut property="propertyName" [ param="parameterName"] permet de mettre à jour un attribut du bean. Par défaut, l'alimentation est faite automatiquement avec le paramètre correspondant dans la requête. Si le nom de la propriété et du paramètre sont différents, il faut préciser l'attribut property et l'attribut param contenant le nom du paramètre qui va alimenter la propriété du bean.

Exemple :
<jsp:setProperty name="monBean" property="nom"/>

L'attribut property="propertyName" value="{string | <%= expression %>}" permet d'alimenter la propriété du bean avec une valeur particulière.

Exemple :
<jsp:setProperty name="monBean" property="nom" value="toto" />

Il n'est pas possible d'utiliser param et value dans le même tag.

Exemple : Cette exemple est identique au précédent
<html>
<HEAD>
<TITLE>Essai d'instanciation d'un bean dans une JSP</TITLE>
</HEAD>
<body>
<p>Test d'utilisation d'un Bean dans une JSP </p>
<jsp:useBean id="personne" scope="request" class="test.Personne" />
<p>nom initial = <%= personne.getNom() %></p> 
<jsp:setProperty name="personne" property="nom" value="mon nom" />
<p>nom mis à jour = <%= personne.getNom() %></p>
</body>
</html>

Ce tag peut être utilisé entre les tags <jsp:useBean> et </jsp:useBean> pour initialiser les propriétés du bean lors de son instanciation.

 

78.4.4.3. Le tag <jsp:getProperty>

Le tag <jsp:getProperty> permet d'obtenir la valeur d'un attribut d'un Bean. Le tag utilise le getter (méthode getXXX() où XXX est le nom de la propriété avec la première lettre en majuscule) pour obtenir la valeur et l'insérer dans la page HTML générée. Le bean doit exister grâce à un appel au tag <jsp:useBean>.

La syntaxe est la suivante :

<jsp:getProperty name="beanInstanceName" property=" propertyName" />

L'attribut name indique le nom du bean tel qu'il a été déclaré dans le tag <jsp:useBean>.

L'attribut property indique le nom de la propriété dont on veut la valeur.

Exemple :
<html>
<HEAD>
<TITLE>Essai d'instanciation d'un bean dans une JSP</TITLE>
</HEAD>
<body>
<p>Test d'utilisation d'un Bean dans une JSP </p>
<jsp:useBean id="personne" scope="request" class="test.Personne" />
<p>nom initial = <jsp:getProperty name="personne" property="nom" /></p>
<jsp:setProperty name="personne" property="nom" value="mon nom" />
<p>nom mise à jour = <jsp:getProperty name="personne" property="nom" /></p>
</body>
</html>
stop Attention : ce tag ne permet pas d'obtenir la valeur d'une propriété indexée ni les valeurs d'un attribut d'un EJB.

Remarque : avec Tomcat 3.1, l'utilisation du tag <jsp:getProperty> sur un attribut dont la valeur est null n'affiche rien alors que l'utilisation d'un tag d'expression retourne « null ».

Exemple :
<html>
<HEAD>
<TITLE>Essai d'instanciation d'un bean dans une JSP</TITLE>
</HEAD>
<body>
<p>Test d'utilisation d'un Bean dans une JSP </p> 
<jsp:useBean id="personne" scope="request" class="test.Personne" />
<p>nom initial = <jsp:getProperty name="personne" property="nom" /></p>
<% personne.setNom(null);%>
<p>nom mis à jour = <jsp:getProperty name="personne" property="nom" /></p>
<p>nom mis à jour = <%= personne.getNom() %></p>
</body>
</html>

 

78.4.4.4. Le tag de redirection <jsp:forward>

Le tag <jsp:forward> permet de rediriger la requête vers une autre URL pointant vers un fichier HTML, JSP ou une servlet.

Dès que le moteur de JSP rencontre ce tag, il redirige le requête vers l'URL précisée et ignore le reste de la JSP courante. Tout ce qui a été généré par la JSP est perdu.

La syntaxe est la suivante :

<jsp:forward page="{relativeURL | <%= expression %>}" />
ou
<jsp:forward page="{relativeURL | <%= expression %>}" >
<jsp:param name="parameterName" value="{ parameterValue | <%= expression %>}" /> +
</jsp:forward>

L'option page doit contenir la valeur de l'URL de la ressource vers laquelle la requête va être redirigée.

Cette URL est absolue si elle commence par un '/' sinon elle est relative à la JSP . Dans le cas d'une URL absolue, c'est le serveur web qui détermine la localisation de la ressource.

Il est possible de passer un ou plusieurs paramètres vers la ressource appelée grâce au tag <jsp :param>.

Exemple : Test8.jsp
<html> 
<body> 
<p>Page initiale appelée</p>
<jsp:forward page="forward.htm"/>
</body>
</html>
Exemple : forward.htm
<HTML>
<HEAD>
<TITLE>Page HTML</TITLE>
</HEAD>
<BODY>
<p><table border="1" cellpadding="4" cellspacing="0" width="30%" align=center >
<tr bgcolor="#A6A5C2">
<td align="center">Page HTML forwardée</Td>
</Tr>
</table></p>
</BODY>
</HTML>

Dans l'exemple, le fichier forward.htm doit être dans le même répertoire que la JSP. Lors de l'appel à la JSP, c'est la page HTML qui est affichée. Le contenu généré par la page JSP n'est pas affiché.

 

78.4.4.5. Le tag <jsp:include>

Ce tag permet d'inclure dynamiquement le contenu généré par une JSP ou une servlet au moment où la JSP est exécutée. C'est la différence avec la directive include pour laquelle le fichier est inséré dans la JSP avant la génération de la servlet.

La syntaxe est la suivante :

<jsp:include page="relativeURL" flush="true" />

L'attribut page permet de préciser l'URL relative de l'élément à insérer.

L'attribut flush permet d'indiquer si le tampon doit être envoyé au client et vidé. Si la valeur de ce paramètre est true, il n'est pas possible d'utiliser certaines fonctionnalités dans la servlet ou la JSP appelée : il n'est pas possible de modifier l'entête de la réponse (header, cookies) ou de faire suivre vers une autre page.

Exemple :
<html>
  <body>
    <jsp:include page="bandeau.jsp"/>
    <H1>Bonjour</H1>
    <jsp:include page="pied.jsp"/>
  </body>
</html>

Il est possible de fournir des paramètres à la servlet ou à la JSP appelée en utilisant le tag <jsp:param>.

 

78.4.4.6. Le tag <jsp:plugin>

Ce tag permet la génération du code HTML nécessaire à l'exécution d'une applet en fonction du navigateur : un tag HTML <Object> ou <Embed> est généré en fonction de l'attribut User-Agent de la requête.

Le tag <jsp:plugin> possède trois attributs obligatoires :

Attribut Rôle
code permet de préciser le nom de classe
codebase contient une URL précisant le chemin absolu ou relatif du répertoire contenant la classe ou l'archive
type les valeurs possibles sont applet ou bean

Il possède aussi plusieurs autres attributs optionnels dont les plus utilisés sont :

Attribut Rôle
align permet de préciser l'alignement de l'applet : les valeurs possibles sont bottom, middle ou top
archive permet de préciser un ensemble de ressources (bibliothèques jar, classes, ...) qui seront automatiquement chargées. Le chemin de ces ressources tient compte de l'attribut codebase
height précise la hauteur de l'applet en pixel ou en pourcentage
hspace précise le nombre de pixels insérés à gauche et à droite de l'applet
jreversion précise la version minimale du jre à utiliser pour faire fonctionner l'applet
name précise le nom de l'applet
vspace précise le nombre de pixels insérés en haut et en bas de l'applet
width précise la longueur de l'applet en pixel ou en pourcentage

Pour fournir un ou plusieurs paramètres, il faut utiliser dans le corps du tag <jsp:plugin> le tag <jsp:params>. Chaque paramètre sera alors défini dans un tag <jsp:param>.

Exemple :
<jsp:plugin type="applet" code="MonApplet.class" codebase="applets" 
	  jreversion="1.1" width="200" height="200" >
  <jsp:params>
     <jsp:param name="couleur" value="eeeeee" />
  </jsp:params>
</jsp:plugin>

Le tag <jsp:fallback> dans le corps du tag <jsp:plugin> permet de préciser un message qui sera affiché dans les navigateurs ne supportant pas le tag HTML <Object> ou <Embed>.

 

78.5. Un exemple très simple

L'exemple de cette section est composé de deux pages.

La premiere page est une page HTML qui demande à l'utilisateur son nom et invoque une url vers une JSP.

Exemple : TestJSPIdent.html
<HTML>
<HEAD>
<TITLE>Identification</TITLE>
</HEAD>
<BODY>
<FORM METHOD=POST ACTION="jsp/TestJSPAccueil.jsp">
Entrez votre nom : 
<INPUT TYPE=TEXT NAME="nom">
<INPUT TYPE=SUBMIT VALUE="SUBMIT">
</FORM>
</BODY>
</HTML>

La page JSP salue l'utilisateur en récupérant son nom.

Exemple : TestJSPAccueil.jsp
<HTML> 
<HEAD> 
<TITLE>Accueil</TITLE>
</HEAD> 
<BODY> 
<% 
String nom = request.getParameter("nom"); 
%> 
<H2>Bonjour <%= nom %></H2> 
</BODY> 
</HTML>

 

78.6. La gestion des erreurs

Lors de l'exécution d'une page JSP, des erreurs peuvent survenir. Chaque erreur se traduit par la levée d'une exception. Si cette exception est capturée dans un bloc try/catch de la JSP, celle-ci est traitée. Si l'exception n'est pas capturée dans la page, il y a deux possibilités selon qu'une page d'erreur est associée à la page JSP ou non :

  • sans page d'erreur associée, la pile d'exécution de l'exception est affichée
  • avec une page d'erreur associée, une redirection est effectuée vers cette JSP

La définition d'une page d'erreur permet de la préciser dans l'attribut errorPage de la directive page des autres JSP de l'application. Si une exception est levée dans les traitements d'une de ces pages, la JSP va automatiquement rediriger l'utilisateur vers la page d'erreur précisée.

La valeur de l'attribut errorPage de la directive page doit contenir l'URL de la page d'erreur. Le plus simple est de définir cette page à la racine de l'application web et de faire précéder le nom de la page par un caractère '/' dans l'url.

Exemple :
<%@ page errorPage="/mapagederreur.jsp" %>

 

78.6.1. La définition d'une page d'erreur

Une page d'erreur est une JSP dont l'attribut isErrorPage est égal à true dans la directive page. Une telle page dispose d'un accès à la variable implicite nommée exception de type Throwable qui encapsule l'exception qui a été levée.

Il est possible dans une telle page d'afficher un message d'erreur personnalisé mais aussi d'inclure des traitements liés à la gestion de l'exception : ajouter l'exception dans un journal, envoyer un mail pour son traitement, ...

Exemple :
<%@ page language="java" contentType="text/html" %>
%@ page isErrorPage="true" %>
<html>
  <body>
    <h1>Une erreur est survenue lors des traitements</h1>
    <p><%= exception.getMessage() %></p>
  </body>
</html>

 

78.7. Les bibliothèques de tags personnalisés (custom taglibs)

Les bibliothèques de tags (taglibs) ou tags personnalisés (custom tags) permettent de définir ses propres tags basés sur XML, de les regrouper dans une bibliothèque et de les réutiliser dans des JSP. C'est une extension de la technologie JSP apparue à partir de la version 1.1 des spécifications des JSP.

 

78.7.1. La présentation des tags personnalisés

Un tag personnalisé est un élément du langage JSP défini par un développeur pour des besoins particuliers qui ne sont pas traités en standard par les JSP. Ces dernières permettent de définir ses propres tags qui réaliseront des actions pour générer la réponse.

Le principal but est de favoriser la séparation des rôles entre le développeur Java et le concepteur de pages web. L'idée maitresse est de déporter le code Java contenu dans les scriplets de la JSP dans des classes dédiées et de les appeler dans le code source de la JSP en utilisant des tags particuliers.

Ce concept peut sembler proche de celui des javabeans dont le rôle principal est aussi de définir des composants réutilisables. Les javabeans sont particulièrement adaptés pour stocker et échanger des données entre les composants de l'application web en passant par la session.

Les tags personnalisés sont adaptés pour enlever du code Java inclus dans les JSP et le déporter dans une classe dédiée. Cette classe est physiquement un javabean qui implémente une interface particulière.

La principale différence entre un javabean et un tag personnalisé est que ce dernier tient compte de l'environnement dans lequel il s'exécute (notamment la JSP et le contexte de l'application web ) et interagit avec lui.

Pour de plus amples informations sur les bibliothèques de tags personnalisés, il suffit de consulter le site qui leur est consacré :
https://www.oracle.com/java/technologies/java-server-tag-library.html.

Les tags personnalisés possèdent des fonctionnalités intéressantes :

  • ils ont un accès aux objets de la JSP notamment l'objet de type HttpResponse. Ils peuvent donc modifier le contenu de la réponse générée par la JSP
  • ils peuvent recevoir des paramètres envoyés à partir de la JSP qui les appelle
  • ils peuvent avoir un corps qu'ils peuvent manipuler. Par extension de cette fonctionnalité, il est possible d'imbriquer un tag personnalisé dans un autre avec un nombre d'imbrications illimité

Les avantages des bibliothèques de tags personnalisés sont :

  • une suppression du code Java dans la JSP remplacé par un tag XML facilement compréhensible ce qui simplifie grandement la JSP
  • une API facile à mettre en oeuvre
  • une forte et facile réutilisabilité des tags développés
  • une maintenance des JSP facilitée

La définition d'une bibliothèque de tags comprend plusieurs entités :

  • une classe dite "handler" pour chaque tag qui compose la bibliothèque
  • un fichier de description de la bibliothèque

 

78.7.2. Les handlers de tags

Chaque tag est associé à une classe qui va contenir les traitements à exécuter lors de l'utilisation du tag. Une telle classe est nommée "handler de tag" (tag handler). Pour permettre son appel, une telle classe doit obligatoirement implémenter directement ou indirectement l'interface javax.servlet.jsp.tagext.Tag

L'interface Tag possède une interface fille BodyTag qui doit être utilisée dans le cas où le corps du tag est utilisé.

Pour plus de facilité, l'API JSP propose les classes TagSupport et BodyTagSupport qui implémentent respectivement l'interface Tag et BodyTag. Ces deux classes, contenues dans le package javax.servlet.jsp.tagext, proposent des implémentations par défaut des méthodes de l'interface. Ces deux classes proposent un traitement standard par défaut pour chacune des méthodes de l'interface qu'elles implémentent. Pour définir un handler de tag, il suffit d'hériter de l'une ou l'autre de ces deux classes.

Les méthodes définies dans les interfaces Tag et BodyTag sont appelées, par la servlet issue de la compilation de la JSP, au cours de l'utilisation du tag.

Le cycle de vie général d'un tag est le suivant :

  • lors de la rencontre du début du tag, un objet du type du handler est instancié
  • plusieurs propriétés sont initialisées (pageContext, parent, ...) en utilisant les setters correspondants
  • si le tag contient des attributs, les setters correspondants sont appelés pour alimenter leurs valeurs
  • la méthode doStartTag() est appelée
  • si la méthode doStartTag() renvoie la valeur EVAL_BODYINCLUDE alors le contenu du corps du tag est évalué
  • lors de la rencontre de la fin du tag, appel de la méthode doEndTag()
  • si la méthode doEndTag() renvoie la valeur EVAL_PAGE alors l'évaluation de la page se poursuit, si elle renvoie la valeur SKIP_PAGE elle ne se poursuit pas

Toutes ces opérations sont réalisées par le code généré lors de la compilation de la JSP.

Un handler de tag possède un objet qui permet d'avoir un accès aux objets implicites de la JSP. Cet objet est du type javax.servlet.jsp.PageContext

Comme le code contenu dans la classe du tag ne peut être utilisé que dans le contexte particulier du tag, il peut être intéressant de sortir une partie de ce code dans une ou plusieurs classes dédiées qui peuvent être éventuellement des beans.

Pour compiler ces classes, il faut obligatoirement que le jar de l'API servlets (servlets.jar) soit inclus dans la variable CLASSPATH.

 

78.7.3. L'interface Tag

Cette interface définit les méthodes principales pour la gestion du cycle de vie d'un tag personnalisé qui ne doit pas manipuler le contenu de son corps.

Elle définit plusieurs constantes :

Constante Rôle
EVAL_BODY_INCLUDE Continuer avec l'évaluation du corps du tag
EVAL_PAGE Continuer l'évaluation de la page
SKIP_BODY Empêcher l'évaluation du corps du tag
SKIP_PAGE Empêcher l'évaluation du reste de la page

Elle définit aussi plusieurs méthodes :

Méthode Rôle
int doEndTag() Traitements à la rencontre du tag de fin
int doStartTag() Traitements à la rencontre du tag de début
setPageContext(Context) Sauvegarde du contexte de la page

La méthode doStartTag() est appelée lors de la rencontre du tag d'ouverture et contient les traitements à effectuer dans ce cas. Elle doit renvoyer un entier prédéfini qui indique comment va se poursuivre le traitement du tag :

  • EVAL_BODY_INCLUDE : poursuite du traitement avec évaluation du corps du tag
  • SKIP_BODY : poursuite du traitement sans évaluation du corps du tag

La méthode doEndTag() est appelée lors de la rencontre du tag de fermeture et contient les traitements à effectuer dans ce cas. Elle doit renvoyer un entier prédéfini qui indique comment va se poursuivre le traitement de la JSP.

  • EVAL_PAGE : poursuite du traitement de la JSP
  • SKIP_PAGE : ne pas poursuivre le traitement du reste de la JSP

 

78.7.4. L'accès aux variables implicites de la JSP

Les tags ont accès aux variables implicites de la JSP dans laquelle ils s'exécutent grâce à un objet de type PageContext. La variable pageContext est un objet de ce type qui est initialisé juste après l'instanciation du handler.

Le classe PageContext est une classe abstraite dont l'implémentation des spécifications doit fournir une adaptation concrète.

Cette classe définit plusieurs méthodes :

Méthodes Rôles
JspWriter getOut() Permet un accès à la variable out de la JSP
Exception getException() Permet un accès à la variable exception de la JSP
Object getPage() Permet un accès à la variable page de la JSP
ServletRequest getRequest() Permet un accès à la variable request de la JSP
ServletResponse getResponse() Permet un accès à la variable response de la JSP
ServletConfig getServletConfig() Permet un accès à l'instance de la variable de type ServletConfig
ServletContext getServletContext() Permet un accès à l'instance de la variable de type ServletContext
HttpSession getSession() Permet un accès à la session
Object getAttribute(String) Renvoie l'objet associé au nom fourni en paramètre dans la portée de la page
setAttribute(String, Object) Permet de placer dans la portée de la page un objet dont le nom est fourni en paramètre

 

78.7.5. Les deux types de handlers

Il existe deux types de handlers :

  • les handlers de tags sans corps
  • les handlers de tags avec corps

 

78.7.5.1. Les handlers de tags sans corps

Pour définir le handler d'un tag personnalisé sans corps, il suffit de définir une classe qui implémente l'interface Tag ou qui héritent de la classe TagSupport. Il faut définir ou redéfinir les méthodes doStartTag() et endStartTag().

La méthode doStartTag() est appelée à la rencontre du début du tag. Cette méthode doit contenir le code à exécuter dans ce cas et renvoyer la constante SKIP_BODY puisque le tag ne contient pas de corps.

 

78.7.5.2. Les handlers de tags avec corps

Le cycle de vie d'un tel tag inclut le traitement du corps si la méthode doStartTag() renvoie la valeur EVAL_BODY_TAG.

Dans ce cas, les opérations suivantes sont réalisées :

  • la méthode setBodyContent() est appelée
  • le contenu du corps est traité
  • la méthode doAfterBody() est appelée. Si elle renvoie la valeur EVAL_BODY_TAG, le contenu du corps est de nouveau traité

 

78.7.6. Les paramètres d'un tag

Un tag peut avoir un ou plusieurs paramètres qui seront transmis à la classe par des attributs. Pour chacun des paramètres, il faut définir des getters et des setters en respectant les règles et conventions des Java beans. Il est impératif de définir un champ, un setter et éventuellement un accesseur pour chaque attribut.

La JSP utilisera le setter pour fournir à l'objet la valeur de l'attribut.

Au moment de la génération de la servlet par le moteur de JSP, celui-ci vérifie par introspection la présence d'un setter pour l'attribut concerné.

 

78.7.7. La définition du fichier de description de la bibliothèque de tags (TLD)

Le fichier de description de la bibliothèque de tags (tag library descriptor file) est un fichier au format XML qui décrit une bibliothèque de tags. Les informations qu'il contient concernent la bibliothèque de tags elle-même et aussi chacun des tags qui la compose.

Ce fichier est utilisé par le conteneur Web lors de la compilation de la JSP pour remplacer le tag par du code Java.

Ce fichier doit toujours avoir pour extension .tld. Il doit être placé dans le répertoire web-inf du fichier war ou dans un de ses sous-répertoires. Le plus pratique est de tous les regrouper dans un répertoire nommé par exemple tags ou tld.

Comme tout bon fichier XML, le fichier TLD commence par un prologue :

Exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

La DTD précisée doit correspondre à la version de l'API JSP utilisée. L'exemple précédent concernait la version 1.1, l'exemple suivant concerne la version 1.2

Exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtds/web-jsptaglibrary_1_2.dtd">

Le tag racine du document XML est le tag <taglib>.

Ce tag peut contenir plusieurs tags qui définissent les caractéristiques générales de la bibliothèque. Les tags suivants  sont définis dans les spécifications 1.2 :

Nom Rôle
tlib-version version de la bibliothèque
jsp-version version des spécifications JSP utilisées
short-name nom court de la bibliothèque (optionnel)
uri URI qui identifie de façon unique la bibliothèque : cette URI n'a pas besoin d'exister réellement
display-name nom de la bibliothèque
small-icon (optionnel)
large-icon (optionnel)
description description de la bibliothèque
validator (optionnel)
listener (optionnel)
tag il en faut autant que de tags qui composent la bibliothèque

Pour chaque tag personnalisé défini dans la bibliothèque, il faut un tag <tag>. Ce tag permet de définir les caractéristiques d'un tag de la bibliothèque.

Ce tag peut contenir les tags suivants :

Nom Rôle
name nom du tag : il doit être unique dans la bibliothèque
tag-class nom entièrement qualifié de la classe qui contient le handler du tag
tei-class nom qualifié d'une classe fille de la classe javax.servlet.jsp.tagext.TagExtraInfo (optionnel)
body-content type du corps du tag. Les valeurs possibles sont :
  • JSP : le corps du tag contient des tags JSP qui doivent être interprétés
  • tagdependent : l'interprétation du contenu du corps est faite par le tag
  • empty : le corps doit obligatoirement être vide
La valeur par défaut est JSP
display-name nom court du tag
small-icon nom relatif à la bibliothèque d'un fichier gif ou jpeg contenant une icône. (optionnel)
large-icon nom relatif à la bibliothèque d'un fichier gif ou jpeg contenant une icône. (optionnel)
description description du tag (optionnel)
variable (optionnel)
attribute il en faut autant que d'attributs possédés par le tag (optionnel)
example un exemple de l'utilisation du tag (optionnel)

Pour chaque attribut du tag personnalisé, il faut utiliser un tag <attribute>. Ce tag décrit un attribut d'un tag et peut contenir les tags suivants :

Nom Description
name nom de l'attribut
required booléen qui indique la présence obligatoire de l'attribut
rtexprvalue booléen qui indique si la page doit évaluer l'expression lors de l'exécution. Il faut donc mettre la valeur true si la valeur de l'attribut est fournie avec un tag JSP d'expression <%= %>

Le tag <Variable> contient les tags suivants :

Nom Rôle
name-given  
name-from-attribut  
variable-class nom de la classe de la valeur de l'attribut. Par défaut java.lang.String
declare par défaut : True
scope visibilité de l'attribut. Les valeurs possibles sont :
  • AT_BEGIN
  • NESTED
  • AT_END
Par défaut : NESTED (optionnel)
description description de l'attribut (optionnel)

Chaque bibliothèque doit être définie avec un fichier de description au format xml possédant une extension .tld. Le contenu de ce fichier doit pouvoir être validé avec une DTD fournie par Sun.

Ce fichier est habituellement stocké dans le répertoire web-inf de l'application web ou un de ses sous-répertoires.

Exemple :
<?xml version="1.0" encoding="ISO-8859-1" ?>
  <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>testtaglib</shortname>
  <uri>http://fr.jmdoudoux.dej.taglib</uri>
  <info>Bibliotheque de test des taglibs</info>

  <tag>
  <name>testtaglib1</name>
  <tagclass>fr.jmdoudoux.dej.taglib.TestTaglib1</tagclass>
  <info>Tag qui affiche bonjour</info>
  </tag>
</taglib>

 

78.7.8. L'utilisation d'une bibliothèque de tags

Pour utiliser une bibliothèque de tags, il y a des actions à réaliser au niveau du code source de la JSP et au niveau de conteneur d'applications web pour la déployer.

 

78.7.8.1. L'utilisation dans le code source d'une JSP

Chaque bibliothèque utilisée dans une JSP doit être déclarée avant son utilisation en utilisant la directive taglib. Le plus simple est d'effectuer ces déclarations tout au début du code de la JSP.

Cette directive possède deux attributs :

  • uri : l'URI de la bibliothèque telle que définie dans le fichier de description
  • prefix : un préfixe qui servira d'espace de noms pour les tags de la bibliothèque dans la JSP

    Exemple :
    <%@ taglib uri="/WEB-INF/tld/testtaglib.tld" prefix="maTagLib" %>

    L'attribut uri permet de donner une identité au fichier de description de la bibliothèque de tags (TLD). La valeur fournie peut être :

  • directe (par exemple le nom du fichier avec son chemin relatif)

    Exemple :
    <%@ taglib uri="/WEB-INF/tld/testtaglib.tld" prefix="maTagLib" %>
  • ou indirecte (concordance avec un nom logique défini dans un tag taglib du descripteur de déploiement de l'application web )

    Exemple :
    <%@ taglib uri= "/maTaglib" prefix= "maTagbib" %>

Dans ce dernier cas, il faut ajouter pour chaque bibliothèque un tag <taglib> dans le fichier de description de déploiement de l'application/WEB-INF/web.xml

Exemple :
  <taglib>
    <taglib-uri>/maTagLibTest</taglib-uri>
    <taglib-location>/WEB-INF/tld/testtaglib.tld</taglib-location>
  </taglib>

L'appel d'un tag se fait en utilisant un tag dont le nom a la forme suivante : prefix:tag

Le préfix est celui défini dans la directive taglib.

Exemple : un tag sans corps
<maTagLib:testtaglib1/>
Exemple : un tag avec corps
<prefix:tag>
   ...
</prefix:tag>

Le corps peut contenir du code HTML, du code JSP ou d'autre tag personnalisé.

Le tag peut avoir des attributs si ceux-ci ont été définis. La syntaxe pour les utiliser respecte la norme XML.

Exemple : un tag avec un paramètre constant
<prefix:tag attribut="valeur"/>

La valeur de cet attribut peut être une donnée dynamiquement évaluée lors de l'exécution :

Exemple : un tag avec un paramètre
<prefix:tag attribut="<%= uneVariable%>"/>

 

78.7.8.2. Le déploiement d'une bibliothèque

Au moment de la compilation de la JSP en servlet, le conteneur transforme chaque tag en un appel à un objet du type de la classe associée au tag.

Il y a deux types d'éléments auxquels le conteneur d'applications web doit pouvoir accéder :

  • le fichier de description de la bibliothèque
  • les classes des handlers de tags

Les classes des handlers de tags peuvent être stockées à deux endroits dans le fichier war selon leur format :

  • s'ils sont packagés sous forme de fichiers jar alors ils doivent être placés dans le répertoire /WEB-INF/lib
  • s'ils ne sont pas packagés alors ils doivent être placés dans le répertoire /WEB-INF/classes

 

78.7.9. Le déploiement et les tests dans Tomcat

Tomcat étant l'implémentation de référence pour les technologies servlets et JSP, il est pratique d'effectuer des tests avec cet outil.

La version de Tomcat utilisée dans cette section est la 3.2.1.

Le déploiement se fait en deux étapes :

  • la copie des fichiers
  • l'enregistrement de la bibliothèque

Les classes compilées doivent être copiées dans le répertoire WEB-INF/classes de la webapp si elles ne sont pas packagées dans une archive jar, sinon le ou les fichiers .jar doivent être copiés dans le répertoire WEB-INF/lib.

Le fichier .tld doit être copié dans le répertoire WEB-INF ou dans un de ses sous-répertoires.

Il faut ensuite enregistrer la bibliothèque dans le fichier de configuration web.xml contenu dans le répertoire web-inf du répertoire de l'application web.

Il faut ajouter dans ce fichier, un tag <taglib> pour chaque bibliothèque utilisée par l'application web. Ce tag contient deux informations :

  • l'URI de la bibliothèque contenue dans le tag taglib-uri. Cette URI doit être identique à celle définie dans le fichier de description de la bibliothèque
  • la localisation du fichier de description

Exemple :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
  "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
  <welcome-file-list id="ListePageDAccueil">
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
	
  <taglib>
    <taglib-uri>/maTagLibTest</taglib-uri>
    <taglib-location>/WEB-INF/tld/testtaglib.tld</taglib-location>
  </taglib>
</web-app>

Il ne reste plus qu'à lancer Tomcat si ce n'est pas encore fait et à saisir l'url de la page contenant l'appel au tag personnalisé.

 

78.7.10. Les bibliothèques de tags existantes

Il existe de nombreuses bibliothèques de tags libres ou commerciales disponibles sur le marché. Cette section va tenter de présenter quelques-unes des plus connues et des plus utilisées du monde libre. Cette liste n'est pas exhaustive.

 

78.7.10.1. Struts

Struts est un framework pour la réalisation d'applications web reposant sur le modèle MVC 2.

Pour la partie vue, Struts utilise les JSP et propose en plus plusieurs bibliothèques de tags pour faciliter le développement de cette partie présentation. Struts possède quatre grandes bibliothèques :

  • formulaire HMTL
  • modèles (templates)
  • Javabeans (bean)
  • traitements logiques (logic)

Le site web de Struts se trouve à l'url : https://struts.apache.org/index.html.

Ce framework est détaillée dans le chapitre «Struts».

 

78.7.10.2. JSP Standard Tag Library (JSTL)

JSP Standard Tag Library (JSTL) est une spécification issue du travail du JCP sous la JSR numéro 52. Le chapitre «JSTL (Java server page Standard Tag Library)» fournit plus de détails sur cette spécification.

 

78.7.10.3. Apache Taglibs (Jakarta Taglibs)

Apache Taglibs est un ensemble de taglibs : la plupart a été déclarée deprecated notamment à cause de la standardisation de la JSTL.

Il propose en particulier, la bibliothèque Apache Standard Tag Library qui est une implémentation des versions 1.0, 1.1 et 1.2 de la spécification JSTL.

Le site officiel est à l'url : https://tomcat.apache.org/taglibs/

 

 


[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

78 commentaires Donner une note à l´article (5)

 

Copyright (C) 1999-2022 Jean-Michel DOUDOUX. Vous pouvez copier, redistribuer et/ou modifier ce document selon les termes de la Licence de Documentation Libre GNU, Version 1.1 ou toute autre version ultérieure publiée par la Free Software Foundation; les Sections Invariantes étant constitués du chapitre Préambule, aucun Texte de Première de Couverture, et aucun Texte de Quatrième de Couverture. Une copie de la licence est incluse dans la section GNU FreeDocumentation Licence. La version la plus récente de cette licence est disponible à l'adresse : GNU Free Documentation Licence.