Il est possible de définir ou de modifier des
variables de script via un Tag JSP.
Dans l'exemple précédent, l'interaction entre le Tag
et la page JSP se fait en récupérant la référence de
l'objet avec un getAttribute().
Afin de permettre l'utilisation d'une variable de
script, nous allons créer une classe qui étend
TagExtraInfo
:
La méthode
getVariableInfo()
permet de définir des variables de script créée ou
modifiée par le
Tag
. Elle retourne un
tableau
de
VariableInfo
, qui est constitué de quatre éléments :
Le nom de la variable de script.
Le nom du type de l'objet de la variable.
Un booléen indiquant si il s'agit d'une
nouvelle variable ou pas (c'est à dire si
elle doit être déclaré).
Enfin, le dernier argument définit le bloc
dans lequel la variable sera accessible, il
peut prendre les valeurs suivantes :
VariableInfo.AT_BEGIN
: La variable est définit au début
du tag et accessible jusqu'à la fin
du bloc qui contient le tag.
VariableInfo.AT_END
: La variable est définit à la fin
du tag et accessible jusqu'à la fin
du bloc qui contient le tag.
VariableInfo.NESTED
: La variable est définit au début
du tag et accessible seulement dans
le corps du tag.
Attention, le nom de la variable de script doit
correspondre à un élément dans un des scope (dans
l'ordre: page, request, session, application).
La variable de script est synchronisée avec son
équivalent dans le scope, donc il peut y avoir un
conflit si le même nom est utilisé dans deux scopes
différents.
Pour pouvoir utiliser cette variable, il faut
ajouter la balise <tei-class> dans la définition
du tag dans le TLD :
<p:iteratecount="3">
Ligne numéro <%=line%><br/></p:iterate>
Résultat :
Ligne numéro 0
Ligne numéro 1
Ligne numéro 2
Note :
La méthode
getVariableInfo()
possèdent un
TagData
qui permet d'accéder aux attributs du tag, afin de
pourvoir changer dynamiquement le nom de la scriplet
selon un attribut par exemple.
On peut donc modifier le corps du Tag avant de
l'écrire dans la page JSP.
Par exemple, on va faire un Tag pour empêcher une
partie de code HTML d'être interprété par le
navigateur (c'est à dire en remplaçant les
caractères < et > par < et >...).
On utilisera pour cela la lecture bufférisé de
l'interface BodyTag en héritant de son
implémentation BodyTagsupport :
Explication :
La méthode
doStartTag()
retourne
BodyTag.EVAL_BODY_TAG
afin d'utiliser l'évaluation bufférisé du corps du
Tag
. Dans la méthode
doAfterBody()
, on récupère le corps du tag évalué en String. On
modifie ensuite cette String pour remplacer les
caractères "<", ">", "\t" et "\n" par du code
HTML. Puis on affiche la chaîne ainsi transformé...
Note : Avec les JSP 1.2,
BodyTag.EVAL_BODY_TAG
est déprécié et est remplacé par
BodyTag.EVAL_BODY_BUFFERED
.
A l'utilisation, cela donne :
<p:htmlcode><h1>Example HTML</h1><p>
Un paragraphe de texte avec des mots en <b>gras</b>, et d'autres en <i>italique</i>...
</p></p:htmlcode>
Et on obtient :
<h1>Example HTML</h1><p>
Un paragraphe de texte avec des mots en <b>gras</b>, et d'autres en <i>italique</i>...
</p>
Le fait de pouvoir modifier le corps du
Tag
apporte un plus indéniable par rapport à l'interface
Tag
ou
IterationTag
. En effet, on peut facilement modifier le corps
AVANT de l'écrire sur la page JSP. De ce fait, on
peut réellement changer le formatage du corps dans
on ensemble...
La classe
TagExtraInfo
permet également de valider les attributs du tag
avant de l'exécuter.
Il faut pour cela redéfinir la méthode
isValid()
et utiliser le paramètre TagData pour analyser les
paramètres.
Si
isValid()
retourne false une exception sera lancée.
L'exemple précédent permet d'afficher du code HTML,
mais on peut également vouloir afficher des
scriplets Java ou même des Tag JSP sans qu'ils ne
soient interprété.
<h1>Example HTML</h1><p>
Code Java Fri Dec 10 17:45:19 CET 2004
TagLib : Hello World !
</p>
Il faut spécifier que le corps du tag n'est pas du
code JSP afin qu'il ne soit pas interprété.
Pour cela, on va créer un nouveau Tag htmlJspCode
qui utilisera la même classe que htmlCode, mais en
spécifiant que le corps est dépendant du tag (il ne
sera pas interprété) :
L'API des taglibs propose une interface
TryCatchFinally afin de gérer les exceptions
générées par un Tag.
Si un tag implémente l'interface TryCatchFinally, il
doit implémenter deux nouvelles méthodes :
doCatch() qui correspondra au bloc catch.
doFinally() qui correspondra au bloc finnaly.
Concrètement, cela signifie que si un tag implémente
TryCatchFinally, les appels aux méthodes doXXXX()
des interfaces Tag, IterationTag et BodyTag seront
exécuté à l'intérieur d'un bloc try/catch de la
forme suivante :
Le tag
iterate
est le
parent
du tag
htmlCode
et du tag
htmlJspCode
.
htmlCode
est lui même
parent
du tag
hello
...
Mais il n'existe
aucune parenté
entre
htmlCode
et
htmlJspCode
...
La méthode
getParent()
permet d'accéder au
tag parent
, pour éventuellement interagir avec ce dernier.
A Noter également l'existence de la méthode statique
TagSupport.findAncestorWithClass(Tag,Class)
qui permet de
rechercher
un
parent
selon son type dans la hiérarchie des tags..