Vous êtes sur la page 1sur 31

JSP

JavaServer
Pages

Duane Fields

Éditions Eyrolles
ISBN : 2-212-09228-8

2000
5
Les pages JSP :
une approche orientée
composants

Dans ce chapitre :
• Le modèle JSP basé sur les composants
• Concepts de base des composants JavaBeans
• Interaction avec les composants depuis une page JSP

Les scriptlets et les expressions JSP permettent aux développeurs d’ajouter des éléments
dynamiques aux pages web en intercalant du code Java dans des pages HTML. Bien que ce
soit une approche très probante pour les programmeurs Java qui souhaitent créer des applica-
tions web et des sites attractifs, on peut néanmoins y observer une absence de séparation claire
entre la présentation et l’implémentation. En outre, elle nécessite de la part du développeur
une maîtrise parfaite du langage de programmation Java. Les JSP, hormis les scripts, fournis-
sent une autre approche centrée sur les composants pour la conception de pages dynamiques.
Cette dernière permet aux développeurs d’interagir avec des composants Java, non seulement
via du code Java, mais également en utilisant des balises de style HTML. Cette approche a
pour autre avantage de faciliter le partage clair du travail entre les développeurs d’application
et ceux qui s’occupent du contenu web.

1. Le modèle d’architecture orientée composants des pages JSP


Le modèle JSP est centré sur des composants logiciels appelés JavaBeans. Avant d’étudier
dans le détail les composants JavaBeans, nous allons tout d’abord revenir sur les principes sur
lesquels se fonde une conception orientée composants.
JSP – Java Server Pages
2

1.1. Architectures à base de composants


Les composants sont des éléments indépendants et réutilisables qui encapsulent un comporte-
ment applicatif ou des données en un paquetage distinct. Tels des dispositifs de type « boîtes
noires », ils effectuent des opérations sans révéler leurs mécanismes internes. Comme une
interface abstraite fait le lien entre le comportement applicatif et l’implémentation, il est ainsi
épargné aux utilisateurs les détails complexes d’un code touffu. Les fonctionnalités apportées
n’augmentent pas la complexité globale de l’application. En outre, les composants ne sont pas
exclusifs à une application ni à une utilisation unique. Ils sont utilisés comme des briques
élémentaires dans des projets qui, parfois, n’ont aucun rapport entre eux. L’abstraction et la
réutilisation sont les deux principes essentiels de la conception orientée composant. La
figure 5-1 illustre cette approche en montrant comment on peut combiner des composants
logiciels indépendants.

Figure 5-1
Une application Interface Module
basée sur utilisateur de Composant
du guichet gestion d'accès à la
les composants Base de
automatique des base de
données
comptes données

Les composants sont donc des éléments logiciels réutilisables qui peuvent être reliés pour
construire une application. Un bon modèle de composants minimise le travail de codage des
relations entre les différents éléments de l’application. Le principe des architectures de
composants consiste à utiliser une interface commune pour manipuler des objets avec des
outils de développement, la seule nécessité qui incombe à l’outil étant de prendre en charge
l’interface.

1.2. Avantages des architectures à base de composants


Lorsqu’un architecte entreprend la conception d’une nouvelle maison, il se base sur des
composants qui vont lui permettre tout à la fois de gagner du temps et de réduire les coûts
engagés. Plutôt que de concevoir l’installation électrique à partir de zéro, il va par exemple
utiliser des composants déjà existants. Ainsi cet architecte ne va-t-il pas concevoir des
systèmes de climatisations personnalisés, mais plutôt va-t-il les sélectionner à partir de
modèles déjà disponibles sur le marché. Selon toute probabilité, cet architecte ne possédera
pas le savoir-faire ni les ressources nécessaires qui lui permettraient de concevoir de tels
systèmes. Inversement, le constructeur d’appareils de climatisation n’a aucun savoir-faire en
construction de bâtiments. L’approche orientée composants permet à l’architecte et à l’entre-
preneur de concentrer leurs efforts sur ce que, chacun de leur côté, savent le mieux faire. Il en
va de même en informatique. Les architectures par composants offrent la possibilité de
masquer la complexité d’un composant donné par l’adjonction d’une interface, à travers
laquelle le composant interagit avec son environnement ou avec d’autres composants.
On peut utiliser la même argumentation pour illustrer le concept de réutilisation et d’inter-
changeabilité. L’entreprise de construction a opté pour un climatiseur fixé par des écrous stan-
dard et fonctionnant sur une tension électrique standard. Le propriétaire de la maison pourra
Les pages JSP : une approche orientée composants
CHAPITRE 5
3

ainsi remplacer cet appareil par un nouveau modèle plus performant, et ce sans qu’il doive
reconstruire toute la maison. La normalisation des environnements et des méthodes de
conception a permis d’obtenir des systèmes souples, faciles à maintenir. Les composants logi-
ciels ont été conçus pour opérer dans ces environnements spécifiques. L’existence de règles
prédéfinies qui régissent leur interaction avec les autres composants augmente d’autant leur
interchangeabilité.

Développement de composants
En général, une application basée sur des composants fait intervenir une combinaison de
composants génériques et de composants spécifiques aux besoins de l’application. Les avan-
tages de la réutilisation des composants se font sentir, non seulement parce que différentes
applications peuvent partager des composants, mais également parce qu’ils peuvent être réuti-
lisés, par la même application ou par des applications différentes.
Considérons par exemple une application bancaire qui compte plusieurs interfaces client, un
module d’accès aux employés et une console d’administration. Chacun de ces modules peut
recourir à un même composant, commun, pour accéder à toutes les données nécessaires à
l’affichage d’un compte bancaire. Si ce composant est suffisamment bien conçu, avec toute
l’anticipation nécessaire, il peut être développé de façon à servir dans toute application de
gestion financière.
Une fois que le composant est conçu, son concepteur peut dans une certaine mesure en modi-
fier le fonctionnement interne sans qu’il doive en prévenir tous ses utilisateurs. Pour parvenir
à un tel niveau d’abstraction, il faut définir une interface qui protège l’application des détails
d’implémentation du composant.

1.3. Conception de composants pour les projets web


L’approche par composants est tout indiquée pour la conception d’applications web. Les JSP
offrent désormais aux concepteurs web les principes de conception orientée composant que
les développeurs de logiciels traditionnels avaient toujours utilisés. Il n’est désormais plus
nécessaire d’intégrer directement une logique complexe dans les pages au moyen de scripts ni
de développer le contenu de la page dans une logique de programmation ; les concepteurs
peuvent plus simplement utiliser un format de page HTML autour des composants. En outre,
la propriété de réutilisation des composants minimise le temps consacré au développement et
fait que les projets sont moins complexes.
La séparation de la logique applicative du format de présentation est devenue indispensable
pour les sociétés de développements web, dans lesquelles les équipes sont organisées autour
de membres qui ont des compétences complémentaires, à savoir en général des développeurs
d’application et des développeurs web. Les premiers possèdent un savoir-faire dans des tâches
telles que les échanges d’informations avec une base de données et l’optimisation du code du
serveur en vue d’améliorer les performances, tandis que les seconds sont plus à même de
résoudre les problèmes de présentation (conception d’interface, format du contenu des pages,
etc.). Dans un projet de développement web par composants, les développeurs d’applications
peuvent se concentrer sur la conception des composants qui renferment la logique applicative
et les développeurs web peuvent quant à eux construire l’application autour de ces compo-
sants, en mettant l’accent sur la présentation. Comme l’illustre la figure 5-2, il est clair que le
JSP – Java Server Pages
4

fait de définir des limites entre la fonctionnalité du noyau de l’application et sa présentation


permet une séparation claire des responsabilités entre les équipes de développement.

Figure 5-2
Partage des efforts Domaine des développeurs Java
dans le développement
d’applications web

Présentation Logique
des données applicative

Accès aux
données Base de
données
Domaine des
concepteurs web

1.4. Conception des applications à partir de composants


Pour illustrer les principes de conception orientée composant, on va examiner une application
web d’achat en ligne. Comme dans une application typique d’entreprise, l’utilisateur demande
des données qui sont extraites d’une base de données. Les articles extraits sont ensuite traités,
puis le résultat est affiché à l’utilisateur. Dans cet exemple, on affiche un catalogue de
produits. L’utilisateur y sélectionne les articles à acheter, et le montant total, incluant taxes et
frais de livraison, est calculé, puis présenté à l’utilisateur.
La transaction se termine par l’affichage d’un formulaire en ligne où l’utilisateur saisit sa
commande. Une fois celle-ci traitée, une nouvelle page est renvoyée, qui contient une facture
incluant le montant des taxes et de la livraison. Nos concepteurs de page ne devraient avoir
aucun problème pour créer un formulaire de saisie et une page de facture attractifs, et nos
développeurs peuvent facilement calculer les coûts correspondant aux achats effectués. Seule
l’interaction entre les deux mondes est un peu délicate. Avec quelles technologies peut-on
espérer être bien concevoir une telle application ?
Le catalogue de produits étant mémorisé dans la base de données, cette partie de l’application
doit être rattachée au serveur. En revanche, où seront donc effectués les calculs du montant des
taxes et de la livraison ? Il serait possible d’utiliser une approche de script côté serveur en utili-
sant un langage comme JavaScript. Cependant, JavaScript n’est pas pris en charge par tous les
navigateurs et ferait apparaître nos calculs dans le source de la page. Des calculs critiques
comme ceux que nécessite une facture devraient être confinés au niveau du serveur pour des
raisons de sécurité. On ne souhaite pas que le navigateur du client effectue lui-même cette tâche.
Une approche côté serveur utilisant les scripts JSP pourrait solutionner notre problème. On
peut de cette façon avoir accès aux ressources gérées par le serveur avec une sûreté plus
grande dans l’exécution du code. Cette approche fonctionne bien dans de petits projets mais
Les pages JSP : une approche orientée composants
CHAPITRE 5
5

pose certains problèmes pour des applications telles que celle dont on traite. L’intégration
directe de scripts JSP fait que les codes de conception de page HTML et de logique applica-
tive se mélangent. Tant les concepteurs web que les développeurs applicatifs devront
comprendre par le menu détail les autres parties du projet. Dans ce cas, soit on confie aux
développeurs une tâche d’implémentation réduite à l’essentiel, en demandant alors aux desi-
gners de la peaufiner, soit on demande aux designers de développer de jolis formats de pages,
mais qui ne contiennent pas la logique de l’application, pour ensuite laisser le soin aux déve-
loppeurs de s’occuper du code qui permette de calculer le prix des taxes et de la livraison.
Aucune de ces deux solutions n’est satisfaisante en termes de partage équitable des efforts.
Le problème que pose cette approche apparaît clairement lorsqu’on aborde les questions du
déploiement et des mises à jour éventuelles de l’application. Par exemple, que se passe-t-il si
l’application de ventes sur catalogue développée initialement pour un seul site doit être élargie
(pour cause de succès) à l’ensemble des vingt-huit filiales de la société. Bien entendu, les
taxes diffèrent d’une filiale à une autre. Il faut alors faire vingt-huit copies de la page et trouver
un développeur qui en connaît bien le code pour modifier les scripts JSP. Ensuite, il faut que
les développeurs web modifient le code HTML de chaque page pour faire les adaptations
nécessaires dans chaque filiale et régler les problèmes liés à la marque. Tout au long du cycle
de vie de l’application, il faut donc « bricoler » les calculs, repérer les bogues, augmenter les
délais de livraison, mettre à jour le design et ajouter de nouvelles fonctionnalités. Et ce pour
chacune des vingt-huit versions du code.
Voilà pourquoi on privilégiera l’approche par composants pour développer une application web.
Les pages JSP offrent justement la possibilité d’utiliser des composants dans des pages HTML.
En l’occurrence, on développera des composants pour calculer le montant des taxes et des frais
de livraison, configurables à l’exécution avec des paramètres tels que le taux des taxes locales.
Ces composants serviront alors de base aux développeurs de pages web, sans que ceux-ci aient
à faire appel aux autres développeurs pour modifier le code HTML ou créer une nouvelle
version de la page. Réciproquement, les découvertes de bogues ou les mises à jour du côté
applicatif peuvent se faire indépendamment, sans conséquences sur les activités des concep-
teurs de pages web. Voyons maintenant comment les composants s’intègrent dans les pages JSP,
et plus précisément comment les JSP intègrent le modèle des composants JavaBeans.

2. Fonctionnement des composants JavaBeans


Les composants JavaBeans sont des composants logiciels écrits en Java, conformes aux spécifi-
cations exposées dans l’API des JavaBeans. Cette API qui a été créée par Sun en collaboration
avec d’autres acteurs de l’industrie énonce les règles que doivent suivre les développeurs de
logiciels pour créer des composants logiciels indépendants et réutilisables. Comme beaucoup de
composants logiciels, les JavaBeans renferment un état et un comportement. Par l’utilisation de
balises JSP conçues pour les JavaBeans dans leurs pages web, les développeurs de contenus
peuvent tirer profit de la puissance de Java en ajoutant des éléments dynamiques à leurs pages,
sans pour autant écrire la moindre ligne de code Java. Rappelons tout d’abord les principales
caractéristiques des composants JavaBeans avant de détailler leur utilisation dans les JSP.

Les conteneurs de JavaBeans


Un conteneur JavaBeans est une application, un environnement ou un langage de programma-
tion qui permet aux développeurs de faire appel à des composants, de les configurer et
JSP – Java Server Pages
6

d’accéder à leurs données et à leurs méthodes. Les applications qui se servent directement des
composants JavaBeans sont exclusivement écrites en Java mais les conteneurs permettent de
les utiliser à des niveaux conceptuels plus élevés. Pour cela, les composants JavaBeans expo-
sent leurs fonctionnalités et leur comportement au conteneur. Le développeur peut ainsi les
manipuler d’une façon plus intuitive. Le conteneur JavaBeans définit ses propres critères de
présentation et d’interaction avec le composant et écrit lui-même le code Java qui en résulte.
Si vous avez déjà utilisé les outils visuels Bean Box de Sun, Visual Age pour Java d’IBM,
Visual Café de WebGain ou d’autres outils de développement Java, vous avez donc déjà mani-
pulé des composants. Ces ateliers de développement fonctionnent avec des conteneurs Java-
Beans qui permettent de manipuler visuellement les composants. Ainsi peut-on par le simple
déplacement d’icônes définir les caractéristiques des composants Java, leur comportement,
leur lien avec d’autres objets, et bâtir une application entière. L’application ainsi définie
génère tout le code Java nécessaire. Les conteneurs de JSP, d’une façon similaire, permettent
aux développeurs de créer des applications Java basées sur le web sans récriture de code Java.
L’interaction avec les composants dans les JSP se fait par l’intermédiaire de balises qui
peuvent se mêler à du code HTML classique.

Les propriétés des composants


Les conteneurs permettent de manipuler les composants en termes de propriétés (ce sont des
attributs de composants JavaBeans identifiés par un nom, qui maintiennent son état et contrô-
lent son comportement). Un composant est défini par ces propriétés sans lesquelles il serait
pratiquement inutilisable. Les propriétés d’un composant JavaBeans peuvent être modifiées
pendant l’exécution par le conteneur pour contrôler les spécificités de son comportement. Les
valeurs de ces propriétés constituent le seul mécanisme que le conteneur utilise pour mettre
les JavaBeans à la disposition du développeur.
À titre d’exemple, supposons que l’on possède un JavaBeans WeatherBean qui détient des
informations sur les conditions atmosphériques du moment et des prévisions météorologi-
ques. Le JavaBeans peut récupérer ces informations en accédant aux serveurs du National
Weather Service ou les extraire d’une base de données, sachant que tout comme l’utilisateur
du JavaBeans, il nous est d’aucune utilité de savoir comment ce composant obtient ses infor-
mations. Tout ce qui nous intéresse en tant que développeurs, c’est que WeatherBean soit
capable de nous fournir des informations telles que les températures actuelles, les maximales
attendues ou les risques de précipitations. Chacun de ces éléments d’informations est proposé
au conteneur de JavaBeans sous forme d’une propriété du composant dont les valeurs sont
accessibles par la page ou l’application web.
Chaque composant possédera un ensemble de propriétés en fonction des informations qu’il
contient. On peut le personnaliser en initialisant soi-même les valeurs de ses propriétés. Le
créateur du JavaBeans va imposer des restrictions sur chacune de ses propriétés, ce qui lui
permet de contrôler l’accès qui en est fait. Une propriété peut être accessible en lecture seule-
ment, en écriture seulement ou en mise à jour (lecture/écriture). C’est cette notion d’accessi-
bilité qui permet au concepteur du JavaBeans d’imposer des restrictions sur la façon de
l’utiliser. Ainsi, dans l’exemple WeatherBean, cela n’aurait aucun sens de permettre aux déve-
loppeurs de modifier la valeur de la propriété du composant qui indique la température maxi-
male de la journée. Cette information est gérée par le JavaBeans et ne devrait être accessible
qu’en lecture. D’autre part, si le JavaBeans est doté d’une propriété qui contient le code postal
Les pages JSP : une approche orientée composants
CHAPITRE 5
7

d’une région dont on souhaite connaître la météo, il serait normal de permettre aux déve-
loppeurs de le spécifier. Une telle propriété serait accessible en lecture/écriture.

REMARQUE Les composants JavaBeans sont en fait de simples objets Java, comme cela sera détaillé au chapitre 6.
Les propriétés d’un composant JavaBeans sont reliées à des méthodes d’un objet Java qui gère son état.
Par conséquent, lorsqu’on initialise la propriété d’un JavaBeans, c’est comme si on faisait un raccourci
pour l’appel des méthodes des objets à travers Java. De même, visualiser la valeur courante d’une
propriété d’un JavaBeans revient pour l’essentiel à un appel d’une méthode d’un objet qui retourne cette
valeur comme résultat. On verra au chapitre suivant comment faire correspondre les méthodes d’un objet
Java et les propriétés d’un JavaBeans.

Les propriétés liées et les propriétés de déclenchement


Certaines propriétés sont utilisées comme des déclencheurs, pour déclencher un comporte-
ment ou renvoyer des comptes rendus. La lecture de telles propriétés ou leur modification a
pour conséquence immédiate la réalisation par un composant JavaBeans d’une certaine action
sur le serveur : il peut s’agir mettre à jour les valeurs d’autres propriétés ou de lancer une autre
tâche sur le serveur. La mise à jour de la valeur de la propriété de code postal par exemple
pourrait conduire le JavaBeans à consulter les services du National Weather Service pour
s’informer sur les conditions atmosphériques qui correspondent au nouveau code postal. Il
mettra ensuite à jour ses autres propriétés relatives à la météo en conséquence. Dans ce cas,
les propriétés qui ont trait à la météo et au code postal sont considérées comme des propriétés
liées parce que la modification de la valeur de l’une d’entre elles met à jour les valeurs des
autres.

Les propriétés indexées


Il est également possible pour une propriété unique de mémoriser plusieurs valeurs. Ces
propriétés sont dites indexées car chaque valeur enregistrée dans la propriété est accessible via
un numéro d’indice qui pointe sur la valeur souhaitée. On peut par exemple réclamer la
première valeur de la liste, la troisième ou la vingtième. Ainsi, notre WeatherBean pourrait
avoir une propriété qui prenne en charge les prévisions météorologiques pour les cinq jours à
venir. Cependant, tous les conteneurs de JavaBeans ne fournissent pas un mécanisme simple
pour manipuler directement ces propriétés multivaluées. Par exemple, les balises de Java-
Beans des JSP ne reconnaissent pas les propriétés indexées. Il faut utiliser en lieu et place des
scriptlets, des expressions JSP ou les balises JSP personnalisées (détaillées aux chapitres 13
et 14) pour pouvoir accéder à de telles propriétés.

Les types de données des propriétés


Les propriétés des JavaBeans peuvent être utilisées pour prendre en charge une quantité
importante d’informations. Par exemple, les propriétés de WeatherBean peuvent mémoriser des
informations très diverses comme les températures, les risques de précipitations, les prévi-
sions météo, les codes postaux, etc. Chaque propriété d’un composant JavaBeans ne peut
contenir qu’un type particulier de données. Ses valeurs ont un type Java, qui est utilisé en
interne par le composant et dans le code Java généré par le conteneur des JavaBeans. Les
propriétés peuvent bien entendu supporter n’importe quel type primitif de Java tel que int
(entier simple précision) ou double (entier double précision), ainsi que des objets Java tels que
String et Date. Elles peuvent également mémoriser des objets définis par les utilisateurs, voire
JSP – Java Server Pages
8

même d’autres JavaBeans. Les propriétés indexées mémorisent généralement un tableau de


valeurs qui ont le même type de données.
Le conteneur de JavaBeans détermine la façon dont il convient de manipuler les valeurs de
propriétés d’un composant. On va référencer les valeurs des propriétés par leur type de
données en utilisant des scriptlets et des expressions. Ainsi, si une propriété contient des
valeurs de type « entier », on ne peut obtenir et déposer que des valeurs entières. Cependant,
avec les balises Beans, on traite chaque propriété comme si elle ne contenait que du texte
(String). Lorsqu’on initialise la valeur d’une propriété d’un JavaBeans, on lui transmet du
texte. De même, lorsqu’on effectue une lecture du contenu d’une propriété, on va récupérer du
texte indépendamment du type de données interne utilisé dans le JavaBeans. Cette stratégie
orientée texte permet de manipuler d’une façon qui soit simple les balises Bean de JSP et se
marie bien avec HTML.
Le conteneur de JSP effectue toutes les conversions de type nécessaires. Par exemple,
lorsqu’on initialise une propriété de type entier, le conteneur de JSP fait les appels Java néces-
saires pour convertir les suites de caractères numériques qu’on lui a fournies en une valeur
entière. Bien entendu, ce processus de conversion nous oblige à transmettre les valeurs
textuelles appropriées de façon que Java puisse les convertir correctement dans le type de
données natif. Si une propriété prend en charge des valeurs à virgule flottante, par exemple, une
erreur est générée si on essaie de lui affecter des valeurs comme banane, pain, cent ou (3,9).
Des concepteurs astucieux de JavaBeans peuvent ainsi contrôler les valeurs des propriétés en
acceptant des valeurs de type chaîne de caractères pour des propriétés qui ne sont pas de ce
type et en effectuant eux-mêmes les conversions. Cette technique doit être utilisée pour toute
valeur qui n’est ni une chaîne de caractères ni un type primitif de Java. Par conséquent, il pour-
rait être parfaitement autorisé d’attribuer à une propriété de type entier la valeur cent si le
concepteur du JavaBeans l’a préparée à une telle affectation.

Les feuilles de propriétés d’un JavaBeans


Les possibilités qu’offre un JavaBeans sont énumérées dans un tableau que l’on appelle la feuille
de propriétés ; y sont répertoriées toutes les propriétés mises à disposition par le JavaBeans, avec
leurs niveaux d’accès pour les utilisateurs et leur type Java. Les feuilles de propriétés peuvent
également spécifier des exemples ou des valeurs valides pour chaque propriété du JavaBeans.
Le tableau 5-1 donne la feuille de propriétés du composant WeatherBean.

Tableau 5-1. Exemple de feuille de propriétés

Nom Type d’accès Type Java Exemple de valeur


zipCode lecture, écriture String 77630
currentTemp lecture seule int 87
todaysHigh lecture seule int 101
todaysLow lecture seule int 85
rainOdds (cote de pluie) lecture uniquement float 0.95
forecasts (prévisions) lecture uniquement String[ ] Ensoleillé, Pluvieux, Couvert, Ensoleillé,
Chaud
iconURL lecture uniquement URL http://imageServer/weather/rainy.gif
Les pages JSP : une approche orientée composants
CHAPITRE 5
9

Les feuilles de propriétés permettent aux concepteurs de JavaBeans de décrire les caractéris-
tiques d’un composant à l’intention des utilisateurs, tels que les développeurs de JSP, les
programmeurs de servlets, etc. Le développeur peut, à partir d’une telle feuille, déterminer
quel type d’information le JavaBeans peut contenir et quel type de comportement il offre.
Bien entendu, la feuille peut ne pas suffire pour bien expliquer à un utilisateur le comporte-
ment du JavaBeans. Dans ce cas, des informations supplémentaires sont disponibles dans la
documentation qui est dédiée au composant.

2.1. Les différentes fonctions des composants JavaBeans


Les JavaBeans peuvent être répartis selon trois grandes catégories fonctionnelles : les compo-
sants graphiques utilisés dans les interfaces utilisateur graphiques, les composants de données
qui permettent l’accès aux informations, et les composants de services (appelés aussi worker
beans) qui peuvent effectuer des tâches ou des calculs spécifiques. Bien entendu, un Java-
Beans peut appartenir à plusieurs de ces catégories à la fois.

Les composants graphiques


En raison du développement des composants graphiques, cette utilisation des composants
JavaBeans est une des plus répandues. Ce sont des éléments tels que les champs de textes, les
listes de sélection ou tout objet graphique utile pour la conception d’interface utilisateur. En
regroupant des composants graphiques dans des JavaBeans, les environnements de dévelop-
pement Java peuvent profiter des avantages offerts par le support de la programmation
graphique de ces composants. Les développeurs peuvent créer leurs interfaces simplement en
assemblant les éléments souhaités. Toutefois, comme les composants graphiques ont été
conçus pour s’exécuter avec les applications Java graphiques, ils ne sont pas compatibles avec
les JSP qui sont plus orientées vers la conception d’interfaces HTML.

Les composants de données


On peut avec ces JavaBeans accéder aux données que le composant lui-même n’a pas forcé-
ment la capacité de collecter ou de générer. Le calcul et la collecte des données mémorisées
dans les JavaBeans de données sont de la responsabilité d’un autre composant ou service plus
complexe. Ces JavaBeans ne sont accessibles qu’en lecture. Ils permettent donc de récupérer
des données mais pas de les modifier.
Certains JavaBeans de données permettent d’initialiser des propriétés afin de contrôler le
format et le filtre des données avant de les retourner via d’autres propriétés. Par exemple, un
AccountStatusBean pourrait être doté d’une propriété currentType qui contrôlerait si la
propriété associée au solde du compte retourne les données en dollars, en livres ou en francs
suisses. Les JavaBeans de données, en raison de leur simplicité, sont utiles pour normaliser
l’accès aux informations en fournissant une interface stable.

Les composants de services


Comme leur nom l’indique, ces JavaBeans permettent d’accéder à un comportement ou un
service particulier. C’est la raison pour laquelle ils sont quelquefois appelés les JavaBeans
travailleurs. Ils peuvent extraire des informations des bases de données, effectuer des calculs
ou formater des informations. Comme il n’y a pas d’autre possibilité pour interagir avec un
JavaBeans que de le faire par ses propriétés, on va accéder à ses services de la même façon.
Dans une conception classique, on va initialiser les valeurs de certaines propriétés qui contrôlent
JSP – Java Server Pages
10

le comportement du JavaBeans, pour ensuite lire les résultats de la requête via d’autres
propriétés. Par exemple, un JavaBeans conçu pour accéder à une base de données qui
comporte les numéros de téléphone des employés pourrait avoir une propriété appelée
employee à laquelle on attribuera comme valeur le nom de l’employé dont on souhaite
connaître le numéro de téléphone. L’initialisation de cette propriété déclenche une recherche
dans la base de données et attribue des valeurs aux propriétés phone et email du JavaBeans
correspondant aux informations demandées.
Tous les JavaBeans de services ne vont pas rechercher des informations sur un serveur.
Certains renferment simplement la logique nécessaire pour effectuer des calculs, des conver-
sions ou des opérations. Par exemple, un composant StatistiquesBean pourrait calculer des
moyennes, des valeurs médianes et des écarts types, tandis qu’un composant ConversionMesu-
reBean pourrait permettre aux concepteurs de pages de spécifier une longueur en pouces pour
la convertir en centimètres, par exemple.
Certains JavaBeans de services ne renvoient aucune information. Leur rôle consiste par
exemple à enregistrer des informations dans une base de données ou dans un fichier d’enregis-
trement. Dans ce cas, on peut initialiser la valeur d’une propriété, non pas pour obtenir un
résultat du service, mais simplement pour son effet de bord, c’est-à-dire pour ce qui se passe
sur le serveur. Les JavaBeans de service permettent de séparer clairement les responsabilités
de chacun et, pour chaque équipe, d’avoir des domaines de connaissances propres. Le concep-
teur web n’a pas besoin de comprendre les estimations statistiques et le programmeur n’a pas
besoin de maîtriser les subtilités des formats de page. Une modification dans la présentation
ou dans le programme n’affectera pas les autres présentations ou programmes si l’interface du
JavaBeans n’a pas changé.

3. Les balises de composants des JSP


Maintenant que l’on a, d’une part, expliqué les principes de l’architecture orientée compo-
sants et, d’autre part, détaillé les caractéristiques des composants JavaBeans, on peut entrer
dans les détails de conception. Les JSP sont dotés d’un ensemble de balises Beans qui peuvent
être utilisées pour placer les JavaBeans dans la page, et ensuite accéder à leurs propriétés.
Contrairement aux scriptlets et aux expressions JSP que l’on a examinées dans le chapitre
précédent, nul besoin d’être un programmeur Java pour concevoir des pages en utilisant des
JavaBeans. En fait, nul besoin d’être un programmeur, tout simplement parce que JSP a fait
en sorte que l’on n’ait pas à intégrer les composants dans le code HTML.

3.1. La programmation des composants basée sur les balises


Les JSP ne nécessitent que trois balises simples pour permettre l’interaction avec les compo-
sants JavaBeans. Ces balises permettent de placer des composants Java dans la page, ainsi que
d’avoir accès à leurs propriétés et de pouvoir les modifier. Certains utilisateurs se plaignent de
la simplicité de l’ensemble des balises JSP et préfèrent une approche intégrant plus de fonc-
tionnalités dans des balises semblables à celles de PHP ou ColdFusion. Il est important de
comprendre que l’ensemble des fonctionnalités offert par les balises de JavaBeans de JSP est
volontairement restreint. Il n’est pas dans ses attributions de fournir un langage de programma-
tion complet car, pour ce faire, les programmeurs peuvent utiliser les scriptlets JSP. Au
contraire, les balises de JavaBeans permettent l’utilisation de stratégies de conception orientées
Les pages JSP : une approche orientée composants
CHAPITRE 5
11

composants dans des documents HTML sans que l’auteur de la page n’ait besoin de connaître
un langage de programmation ou de comprendre des concepts de programmation avancés.
Comme on le sait, un langage puissant devient vite complexe. Les concepteurs de JSP ont
donc choisi de s’appuyer sur un ensemble de fonctionnalités principales très simples, en ne
définissant que quelques balises qui utilisent des JavaBeans et en offrant la possibilité de
développer de nouvelles balises personnalisées qui résolvent des problèmes spécifiques. Les
balises classiques permettent de créer des références aux JavaBeans que l’on souhaite utiliser,
d’initialiser les valeurs de n’importe quelle propriété configurable qu’ils pourraient avoir et de
lire des informations à partir des propriétés des JavaBeans. Des balises personnalisées aux
fonctionnalités plus complexes peuvent être développées par des personnes ou des organisa-
tions, et intégrées dans n’importe quel environnement JSP via un mécanisme d’extension
connu sous le nom de bibliothèques de balises personnalisées. Grâce à ce type de balises, le
langage JSP peut être étendu pour supporter des constructions de programmation supplémen-
taires, telles que les conditions et les boucles, ainsi que de nouvelles fonctionnalités comme
l’accès direct aux bases de données. On examinera ces balises personnalisées et les bibliothè-
ques de balises aux chapitres 13 et 14.

Un exemple en guise d’illustration


Nous allons commencer par examiner un code JSP construit autour de composants plutôt
qu’au moyen des scriptlets. Cet exemple montre une petite partie de ce que l’on peut faire avec
une conception orientée composants et va servir de point de départ à notre discussion sur les
fonctionnalités des composants dans les JSP.
<jsp:useBean id="user" class="RegisteredUser" scope="session"/>
<jsp:useBean id="news" class="NewsReports" scope="request">
<jsp:setProperty name="news" property="category" value="financial"/>
<jsp:setProperty name="news" property="maxItems" value="5"/>
</jsp:useBean>
<html>
<body>
Bienvenu <jsp:getProperty name="user" property="fullName"/>,
Votre dernière visite date de
<jsp:getProperty name="user" property="lastVisitDate"/>.
Heureux de vous revoir!
<P>
Il y a <jsp:getProperty name="news" property="newItems"/>
nouveaux articles pour votre plaisir de la lecture. Bons achats et à bientôt.
</body>
</html>
On remarquera à quel point la conception de la page s’est simplifiée. Quelques balises JSP
spécifiques ont suffi à éliminer le code Java de la page. Bien que l’on ne soit encore rentré
dans aucun détail concernant ces balises, il est facile de déduire ce que fait le code d’un simple
coup d’œil : il utilise deux composants, user et news. Le premier nous permet d’accueillir les
visiteurs d’une façon personnalisée et le second contient des articles de journaux susceptibles
de les intéresser. Les balises JSP permettent de comprendre le format de la page dans la
mesure où l’on écrit du HTML, et non pas du code.
JSP – Java Server Pages
12

3.2. L’accès aux composants JSP


Pour interagir avec un composant Java, il faut d’abord spécifier dans la page l’emplacement
de la classe Java qui définit le composant et lui attribuer un nom. On peut ensuite utiliser ce
nom pour accéder aux valeurs mémorisées dans les propriétés du JavaBeans. Il suffit de
maîtriser trois balises JSP simples pour ajouter la conception de page web basée sur les
composants à notre répertoire. On va détailler chacune de ces balises.

La balise <jsp:useBean>
<jsp:useBean> informe la page que l’on souhaite mettre à sa disposition un JavaBeans. Cette
balise est utilisée pour créer un composant ou pour en obtenir un du serveur. Les attributs de
la balise spécifient le type du composant que l’on veut utiliser et lui affectent un nom qui peut
être utilisé pour le référencer. La balise <jsp:useBean> se présente sous deux formes : une
balise vide unique et un couple de balises de début et de fin contenant le corps qui peut être
utilisé pour spécifier des informations de configuration supplémentaires. Dans sa forme la
plus simple, cette balise ne nécessite que deux attributs, id et class. Comme pour toutes les
balises de JSP, on doit entourer chaque valeur d’attribut par des guillemets. Voici la syntaxe de
base pour les deux formes de la balise :
<jsp:useBean id="bean name" class="class name"/>

<jsp:useBean id="bean name" class="class name">


code d’initialisation
</jsp:useBean>
Toutes les valeurs d’attribut possibles que supporte la balise <jsp:useBean> sont présentées
dans le tableau 5-2. On discutera de l’intérêt de chacun de ces attributs dans la suite du
chapitre, mais pour le moment il s’agit de bien distinguer les attributs de base des balises de
Beans.

Tableau 5-2 Attributs de la balise <jsp:useBean>

Attribut Valeur Entité par Exemple de valeur


défaut
id Un identificateur Java Néant myBean
scope page, request, session, application Page session
Class Nom de la classe Java Néant java.util.Date
Type Nom de la classe Java Idem que classe com.manning.jsp.AbstractPerson
beanName Une classe Java ou un Bean sérialisé Néant com.manning.jsp.USCurrency.ser

L’attribut ID
L’attribut id spécifie le nom du composant, une valeur unique qui le désignera dans la page et
au cours de son existence (on verra comment prolonger l’existence d’un JavaBeans par-delà
son utilisation sur la page courante). On peut utiliser des balises <jsp:useBean> pour définir
plus d’un JavaBeans dans une page, voire des instances multiples de la même classe de
composant JavaBeans, tant que chaque composant possède un identificateur unique. Le nom
Les pages JSP : une approche orientée composants
CHAPITRE 5
13

que nous avons choisi pour notre JavaBeans est arbitraire, mais on doit en la matière suivre
quelques règles simples :
• Il doit être unique pour la page.
• Il est tenu compte de la casse.
• Le premier caractère est une lettre.
• Seuls les lettres, les nombres et les soulignés (_) sont autorisés (les espaces ne le sont pas !).

L’attribut class
La valeur de l’attribut class spécifie le nom de la classe du JavaBeans. Les classes Java sont
souvent structurées en paquetages. Ces derniers sont des collections de fichiers de classes
Java, organisées dans un répertoire unique. Les noms des paquetages sont habituellement
composés de plusieurs noms séparés par des points où chaque nom représente un répertoire
dans la hiérarchie du paquetage. À moins que l’on n’ait utilisé la balise <%@ page %> pour
permettre à notre page d’accéder au paquetage du JavaBeans via son attribut import, on doit
spécifier le nom de la classe du composant dans son intégralité. Le nom intégral d’une classe
est constitué du nom du paquetage de la classe et du nom de la classe elle-même. Par conven-
tion, les noms des paquetages commencent par le nom du domaine Internet de leur créateur et
comportent généralement plusieurs niveaux de hiérarchies pour permettre une meilleure orga-
nisation des collections de classes dans des regroupements logiques. Le développeur du
composant va déterminer son paquetage et le nom de sa classe. Certains des noms complets
de classe de JavaBeans ont la forme suivante :
com.manning.RegisteredUserBean
com.deepmagic.beans.database.logging.LogBean
com.blokware.MagicPizzaBean
com.taglib.wdjsp.arch.EmployeeBean
Le nom de la classe à proprement parler est la dernière partie du nom complet. Dans le
premier exemple, il s’agit donc de la classe RegisteredUserBean qui se trouve dans le paque-
tage com.manning. On peut incorporer ce composant sans le nom du paquetage à condition
d’avoir auparavant importé toutes les classes du paquetage :
<%@page import="com.manning.*" %>
<jsp:useBean name="user" class="RegisteredUserBean" />
ou bien :
<jsp:useBean name="user" class="com.manning.RegisteredUserBean" />

L’attribut type
On utilisera rarement cet attribut dans la pratique. L’attribut class de la balise <jsp:useBean>
détermine la classe Java utilisée pour créer le composant JavaBeans. JSP permet toutefois au
conteneur de JSP d’avoir une interprétation plus fine du type du composant, ce qui s’avère
parfois nécessaire lorsque les JavaBeans existent au niveau du serveur mais qu’ils ne sont pas
instanciés par la page courante. Par défaut, le JavaBeans est référencé par le type de classe
correspondant directement à la classe d’objets sous-jacente. Cependant, si l’on doit faire réfé-
rence au composant sous un autre type, par exemple une classe de base ou une interface qu’il
implémente, on peut utiliser l’attribut type de la balise <jsp:useBean>. Le type de classe que
l’on spécifie représente l’objet JavaBeans dans le code Java qui résulte de la phase de compi-
lation de la page JSP. La classe réelle du composant doit, bien entendu, être compatible avec
JSP – Java Server Pages
14

le type de classe spécifié. Si l’on utilise l’attribut class et type à la fois, le JavaBeans va être
créé en utilisant la classe donnée, puis va subir une modification de type (cast) vers le type
spécifié. L’attribut type ne peut être utilisé seul (sans l’attribut class correspondant) que dans
les cas où le composant JavaBeans existe déjà au niveau du serveur – comme on le verra dans
la dernière section de ce chapitre consacrée à la portée des composants.

Le corps d’une balise


La portion corps d’une balise, optionnelle, peut être utilisée pour initialiser les propriétés
configurables du JavaBeans par l’utilisateur. Cela permet de paramétrer un composant spéci-
fiquement pour cette page ou pour une application particulière. Mais nous reviendrons plus en
détail sur l’initialisation des composants JavaBeans. Pour l’heure, nous parlerons de compo-
sants qui ne nécessitent aucune initialisation lors de leur création.

Fonctionnement de la balise <jsp:useBean>


Entrons maintenant dans le vif du sujet pour examiner comment on utilise les balises de
composants. Voici un exemple de fonctionnement de la balise <jsp:useBean> :
<jsp:useBean id="myclock" class="com.manning.jsp.ClockBean"/>
<html>
<body>
Il y a un Bean caché dans cette page !
</body>
</html>
On a indiqué dans cette page que l’on va utiliser un JavaBeans défini dans le fichier de classe
Java ClockBean, qui se trouve dans le paquetage com.manning.jsp, et on l’a nommé myclock. Ce
nom va être utilisé dans la page. Dans la pratique, on préfère mettre toutes nos balises
<jsp:useBean> au début du document HTML, mais il est correct d’un point de vue syntaxique
de les mettre n’importe où dans la page. Cependant, il faut savoir qu’un JavaBeans n’est acces-
sible que dans la partie de la page qui suit la balise <jsp:useBean> dans laquelle il a été défini.
Toute tentative pour y accéder avant l’apparition de la balise qui le définit génère une erreur.
La balise <jsp:useBean> crée une instance du composant et lui affecte l’ID tel qu’il a été
précisé dans l’attribut id. Lorsque le nouvel objet est créé, il effectue les tâches ou les traite-
ments de données que son concepteur lui a attribués. Par exemple, ClockBean initialise son état
interne pour traduire l’heure et la date actuelles, alors qu’un autre composant peut rechercher
des informations dans une base de données. Tout cela est partie intégrante du processus ordi-
naire d’instanciation de Java et se produit sans que l’on intervienne. Lorsqu’un nom a été
attribué au JavaBeans et que ce dernier est devenu accessible à la page, on peut commencer à
utiliser ses propriétés. En fonction de sa conception, les propriétés peuvent soit tout simple-
ment fournir des informations telles que l’heure ou le nom de l’utilisateur courant, soit
exécuter des transactions complexes ou rechercher des informations dans une base de
données. Quoi qu’il en soit, les résultats sont accessibles depuis les propriétés du JavaBeans.
Il est important de bien différencier la classe d’un JavaBeans de son instance. La classe d’un
JavaBeans contrôle la création de son type, ses propriétés et ses fonctionnalités. Elle est
utilisée comme un motif pour créer une instance unique du composant JavaBeans à chaque
appel de la balise <jsp:useBean>. Par exemple, considérons les balises suivantes :
<jsp:useBean id="clock1" class="com.manning.jsp.ClockBean" />
<jsp:useBean id="clock2" class="com.manning.jsp.ClockBean" />
Les pages JSP : une approche orientée composants
CHAPITRE 5
15

Ces balises créent deux objets JavaBeans indépendants ; chacun possède son propre nom :
clock1 et clock2. Ce sont des instances de la même classe, mais tout changement dans l’un est
sans effet sur l’autre. Plus bas dans ce chapitre, on verra comment d’autres attributs de la
balise <jsp:useBean> peuvent permettre de réutiliser un composant JavaBeans entre plusieurs
accès à la même page ou depuis plusieurs pages du site. Dans les exemples précédents, les
composants JavaBeans n’étaient que présents dans le code. Nous allons maintenant montrer
comment les utiliser avec la balise <jsp:getProperty>, qui permet d’extraire les informations
contenues dans les JavaBeans.
Accès aux propriétés des composants via <jsp:getProperty>
Pour accéder aux propriétés d’un JavaBeans depuis les JSP, on peut tout d’abord utiliser la
balise <jsp:getProperty>. Contrairement à la balise <jsp:useBean> qui effectue une tâche en
arrière-plan mais ne produit aucune sortie, la balise <jsp:getProperty> produit un contenu
visible dans le code HTML généré par la page. <jsp:getProperty> est vide et en attente de
deux attributs, name et property. Sa syntaxe est la suivante :
<jsp:getProperty name="nm du Bean" property="nom de la propriété" />
L’attribut name désigne le composant que l’on est en train d’évaluer. Il doit correspondre au
nom que l’on a choisi d’attribuer à ce dernier dans l’attribut id de la balise <jsp:useBean>. Il
faut bien garder à l’esprit que la balise <jsp:useBean> fait référence à un composant avec
l’attribut id, tandis que les autres balises y font référence par le nom qui apparaît dans
l’attribut name. C’est une convention JSP qui stipule que l’attribut id doit être utilisé pour
définir un nouvel objet, alors que l’attribut name est utilisé pour faire référence à un objet exis-
tant. Il faut veiller à ne pas confondre les deux utilisations.
Dans le code HTML résultant qui est affiché à l’exécution, la balise est remplacée par la
valeur de la propriété du JavaBeans demandé. Bien entendu, comme on est en train de créer
un document HTML, la propriété est d’abord convertie en texte par le conteneur de JSP. Cette
balise est facile à utiliser. Reprenons l’exemple du composant ClockBean, mais utilisons cette
fois-ci la balise <jsp:getProperty> pour en extraire l’heure courante :
<jsp:useBean id="myclock" class="com.manning.jsp.ClockBean"/>
<html>
<body>
Le composant Java précise qu’il est :
<jsp:getProperty name="myclock" property="time"/>
</body>
</html>
Cela a pour effet d’afficher du code HTML qui a la forme suivante :
<html>
<body>
Le Bean précise qu’il est : 12:33 pm
</body>
</html>
Dans la mesure où cette balise est l’élément central de la génération par les JSP des sorties
dynamiques basées sur les composants, on fera beaucoup faire appel à la <jsp:getProperty>.
On peut utiliser autant de balises <jsp:getProperty> qu’on le souhaite. Il est possible de les
agrémenter de code HTML, non seulement pour générer des valeurs élémentaires et des blocs
JSP – Java Server Pages
16

de texte, mais aussi pour contrôler les attributs de ce code HTML. En effet, il est parfaitement
correct d’adjoindre des balises JSP aux attributs HTML. La propriété d’un composant peut
tout à fait être utilisée pour contrôler la couleur du fond de la page, la largeur d’un tableau ou
la source d’une image. Par exemple, un JavaBeans représentant la charte graphique d’une
entreprise peut faire appel à une propriété qui indique l’emplacement de la dernière version du
logo et la structure des couleurs de l’entreprise. On peut afficher cette image dans du code
HTML sans coder la valeur de l’URL dans chaque page, de la façon suivante :
<jsp:useBean id="style" class="beans.CorporateStyleBean"/>
<html>
<body bgcolor="<jsp:getProperty name="style" property="color"/>">
<center>
<img src="<jsp:getProperty name="style" property="logo"/>">
Bienvenue !
</center>
</body>
</html>
Ce qui va générer le code HTML suivant :
<html>
<body bgcolor="pink"><center>
<img src="http://imageserver/logo.gif">
Bienvenue!
</center>
</body>
</html>
Si le logo doit être modifié la semaine suivante parce que la société a remplacé le directeur du
groupe ou a été rachetée, toutes les pages vont systématiquement afficher la nouvelle valeur
conçue dans CorporateStyleBean. Autre avantage, les programmeurs d’application peuvent
faire appel au même composant pour afficher la marque dans leurs interfaces graphiques et
que toute modification est immédiatement visible.

ASTUCE Conformément aux spécifications, les espaces dans un document ne sont pas prises en charge par
l’analyseur JSP, mais seront préservées par le processeur de JSP. Cependant, dans certaines des implé-
mentations rencontrées, l’analyseur ne conservait pas correctement les caractères d’espacements entre
les balises JavaBeans de JSP s’il n’y avait pas d’autres caractères. Par exemple, le code JSP suivant
devrait afficher « Prénom Nom » alors qu’il peut arriver que l’on obtienne « PrénomNom » :
<jsp:getProperty name="user" property="prenom"/>
<jsp:getProperty name="user" property="nom"/>
Cela se produit souvent parce que l’analyseur JSP ignore le saut de ligne, qui d’ordinaire est traité comme
un caractère d’espacement. Si tel est le cas, ajouter des lignes blanches n’est pas la solution car l’analy-
seur va tout simplement les ignorer, en supposant qu’il n’y a aucun contenu pertinent entre les deux bali-
ses de composant.
Si un conteneur de JSP présente cette anomalie, on peut contourner le problème en insérant des conte-
nus significatifs mais vides, comme un commentaire HTML, qui vont le forcer à préserver le saut de page
dans les sorties.
<jsp:getProperty name="user" property="prenom"/>
<!-- insert a space -->
<jsp:getProperty name="user" property="nom"/>
Les pages JSP : une approche orientée composants
CHAPITRE 5
17

La balise <jsp:setProperty>
La balise <jsp:setProperty> permet de modifier les propriétés d’un composant. Cette balise
peut être utilisée n’importe où dans la page, à condition que le développeur du composant ait
autorisé l’accès en écriture à cette propriété. La modification des valeurs d’une propriété de
composant sert soit à paramétrer son opération, soit à accéder à ses services. Le comportement
qui résulte d’une modification de la valeur d’une propriété est spécifique au composant
concerné. À titre d’exemple, on pourrait trouver un composant doté d’une propriété query
spécifiant une requête vers une base de données, et dont le résultat est enregistré dans d’autres
propriétés. Dans ce cas, on peut appeler <jsp:setProperty> à plusieurs reprises dans la page
et consulter plusieurs fois les propriétés des résultats puisqu’elles vont retourner de nouvelles
valeurs après chaque modification de la propriété query.
La plupart des JavaBeans de service doivent être dotés de propriétés configurables à l’exécution,
pour que leur comportement puisse dépendre de l’utilisateur. Ainsi, on pourra utiliser le même
JavaBeans pour consulter des types d’information différents. Par exemple, si un développeur
crée un JavaBeans pour fournir des informations sur un utilisateur du système, celui-là peut être
réutilisé pour chaque utilisateur, plutôt que d’être décliné un grand nombre de fois (BobBean,
SueBean, JoeBean, etc). Le développeur va plutôt concevoir les propriétés du composant pour
qu’il fasse référence d’une façon abstraite aux caractéristiques de chaque utilisateur, et ensuite
faire en sorte qu’une de ses propriétés stocke ces informations en fonction de l’utilisateur.
La balise <jsp:setProperty> est d’usage simple. Elle nécessite trois attributs : name, property
et value. Comme la balise <jsp:getProperty>, l’attribut name désigne le JavaBeans concerné,
l’attribut property indique les propriétés que l’on souhaite initialiser et l’attribut value est le
texte que l’on veut affecter à la propriété.
<jsp:setProperty name ="nom du Bean" property="nom de la propriété" />
La balise <jsp:setProperty> peut être utilisée n’importe où dans le document JSP après que
le composant a été défini avec la balise <jsp:useBean>. À l’exécution, la page JSP évalue les
balises dans leur ordre d’apparition. Toute valeur de propriété que l’on initialise n’est prise en
compte que dans les balises qui suivent la balise <jsp:setProperty>. L’attribut value peut être
spécifié sous la forme d’un texte ou calculé à l’exécution au moyen d’expressions JSP. Voici
deux façons d’initialiser les jours depuis la dernière visite d’un utilisateur en mettant à jour la
valeur de la propriété. Les deux exemples sont fonctionnellement équivalents, ils affectent la
valeur 30 à la propriété daysLeft :
<jsp:setProperty name="user" property="daysLeft" value="30"/>
<jsp:setProperty name="user" property="daysLeft" value="<%= 15 * 2 %>"/>

Les propriétés indexées


Comme on l’a déjà signalé, les propriétés indexées contiennent plusieurs valeurs de même
type, au lieu d’une seule. Pour accéder à une valeur donnée, on doit transmettre au JavaBeans
le numéro d’indice qui l’identifie parmi les éléments de la propriété indexée. Les balises JSP
prédéfinies ne peuvent pas prendre en charge des propriétés indexées, qui ne sont accessibles
qu’à travers des scriptlets, des expressions ou des balises JSP personnalisées. Examinons par
exemple la propriété forecast de WeatherBean qui contient cinq valeurs String correspondant
aux prévisions météorologiques des cinq jours à venir. Pour visualiser les prévisions du lende-
main, on doit spécifier le premier élément qui, selon la notation tabulaire, est référencé par
l’élément 0, celles d’après-demain par l’élément 1, etc. On peut accéder à une propriété
JSP – Java Server Pages
18

indexée au moyen d’une expression ou d’une scriptlet JSP en faisant simplement appel à sa
méthode d’accès et en lui transmettant une valeur d’indice. Pour consulter une propriété
indexée, il faut la préfixer par le mot get. On peut la modifier en utilisant le préfixe set (on
verra au chapitre 6 comment associer des propriétés aux noms de méthodes). Pour lire la
propriété forecasts, on devra appeler la méthode getForecasts(). Par exemple :
<B>Prévisions pour demain </B>: <%= weather.getForecasts(0) %> <BR>
<B>Pour le reste de la semaine </B>
<UL>
<% for (int index=1; index < 5; index++) { %>
<LI><%= weather.getForecasts(index) %> (peut être)
<% } %>
</UL>
Dans cet exemple, on utilise des scriptlets et des expressions JSP pour accéder à la propriété
forecasts de WeatherBean, qui a été chargée dans la page avec un id d’objet météo. Pour affi-
cher les prévisions météo du lendemain, on utilise une expression JSP pour obtenir le premier
élément de la propriété forecasts en faisant appel à sa méthode d’accès getForecasts() avec
0 comme argument. Ensuite, on utilise une scriptlet pour itérer sur les éléments 1, 2, 3 et 4 afin
de visualiser les prévisions météo du reste de la semaine.
Les JavaBeans dotés de propriétés indexées peuvent être conçus de façon qu’ils soient plus
facilement utilisables avec les pages JSP en évitant au développeur d’avoir recours à des
scriptlets pour y accéder. Un JavaBeans peut contenir une propriété pratique qui permette de
traiter une propriété indexée comme une valeur de texte unique en séparant chaque valeur par
un point-virgule ou un autre délimiteur.

3.3. Initialisation des JavaBeans


Un JavaBeans peut être initialisé à sa création, c’est-à-dire que l’on peut affecter une valeur à ses
propriétés configurables. Cette initialisation ne se fait par défaut qu’au moment de sa création,
autrement dit à chaque fois qu’on accède à la page, puisque par défaut un JavaBeans est créé à
chaque requête. Mais nous verrons lorsqu’on abordera le cycle de vie des composants JavaBeans
que ces derniers peuvent également être mémorisés dans l’environnement du serveur, et obtenus
à partir de celui-ci. Dans ce cas, il n’est pas utile de les réinitialiser à chaque requête.
Dans certains cas, les propriétés qui contrôlent le comportement du composant doivent être
initialisées avant toute tentative de lecture des propriétés. Pour ce faire, l’utilisation de la
balise <jsp:setProperty> au début de la page peut suffire. Toutefois, pour les objets qui ont
une portée dépassant celle d’une requête de page, il est nécessaire de définir un bloc de code
d’initialisation séparé.

Configuration d’un composant JavaBeans


Une version de la balise <jsp:useBean> est munie d’un corps. Elle permet de configurer le
composant avant de l’utiliser, en affectant des valeurs à certaines propriétés au moyen de la
balise <jsp:setProperty>. Cette forme de <jsp:useBean> est entourée de balises ouvrante et
fermante, délimitant le corps de la façon suivante :
<jsp:useBean id="myBean" class="com.manning.jsp.MyBean">
<%-- Emplacement du corps de la balise --%>
</jsp:useBean>
Les pages JSP : une approche orientée composants
CHAPITRE 5
19

Toute commande à l’intérieur du corps est traitée immédiatement après que l’instanciation du
JavaBeans et avant qu’il ne soit mis à la disposition du restant de la page. Par exemple :
<jsp:useBean id="clock" class="com.manning.jsp.ClockBean">
<jsp:setProperty name="clock" property="timezone" value="CST"/>
</jsp:useBean>
On peut considérer les éléments présents dans le corps de la balise <jsp:useBean> comme
faisant partie d’une phase de configuration qui ne s’exécute qu’une seule fois. C’est un moyen
commode pour configurer le JavaBeans avec des données spécifiques à la page ou pour le
préparer à son utilisation future dans la page. Il est même possible d’affecter des valeurs aux
propriétés d’autres composants si ceux-ci ont été créés plus haut dans la page.
Le corps de la balise <jsp:useBean> peut également contenir des scriptlets JSP et des balises
HTML. Cet HTML ne va être affiché comme partie intégrante de la page que si le JavaBeans
doit être instancié (assurez-vous de placer un tel texte après la balise HTML ouvrante !). Si le
JavaBeans existe déjà dans l’environnement, les demandes de pages ultérieures ne vont pas
afficher cet HTML d’initialisation. Par exemple :
<html>
<body>
<jsp:useBean id="clock" class="com.manning.jsp.ClockBean">
Le <b>ClockBean</b> est en cours d’initialisation...
</jsp:useBean>
La page principale suit…
</body>
</html>

Initialisation des composants à partir d’une requête


Une caractéristique importante de la balise <jsp:setProperty> est son aptitude à affecter
dynamiquement, lors de l’exécution, des valeurs aux propriétés des JavaBeans au moyen
des informations obtenues par la requête. On peut ainsi configurer dynamiquement les
composants JavaBeans en intégrant les informations de configuration dans la requête de
page en se basant sur certains événements, comme les entrées utilisateur. Les informations
de requêtes dérivent en réalité de formulaires HTML ou de paramètres de la requête codés
en dur dans l’URL. Elles peuvent également être renseignées avec les valeurs de servlets,
voire des objets entiers. Les formulaires HTML fournissent un procédé simple pour récu-
pérer les données fournies par les utilisateurs et se marient bien avec les couples (nom,
valeur) associés aux propriétés des composants JavaBeans. D’une façon analogue à un
programme CGI, une page JSP peut être utilisée comme un programme de traitement de
formulaire lorsqu’on précise son URL dans l’attribut action de la balise des formulaires.
Toute donnée dans le formulaire va être accessible à la page JSP et pourra fournir des infor-
mations au composant.

Exemple : calcul d’intérêts composés


Le listing 5-1 montre comment on peut concevoir une application simple qui calcule la valeur
des intérêts composés d’un investissement. On va d’abord créer une page HTML et un formu-
laire qui va collecter les informations nécessaires pour effectuer ce calcul :
JSP – Java Server Pages
20

Listing 5-1. CompoundInterest.html


<html>
<body>
<form action="CompoundInterestResults.jsp">
Capital : <input type="text" name="principal">
Taux d’intérêt : <input type="text" name="interestRate">
Années : <input type="text" name="years">
<input type="submit" value="Calcul">
</form>
</body>
</html>
On peut ensuite créer un programme pour utiliser les valeurs spécifiées dans les champs du
formulaire CompoundInterestResults.jsp afin de configurer un composant qui calcule les inté-
rêts composés (la création de ce composant sera décrite dans le chapitre suivant). Pour
l’instant, nous allons nous intéresser au composant en tant que fournisseur de services. Le
tableau 5-3 présente une feuille de propriétés de CompoundInterestBean.

Tableau 5-3 Feuille de propriétés de CompoundInterestBean

Nom Accès Type Java Exemple


principal (capital) lecture, écriture double 100.50
interestRate (taux d’intérêt) lecture, écriture double .10
years (années) lecture, écriture int 10
futureValue (capital dû) lecture uniquement String 155.21

La propriété futureValue est liée aux autres propriétés. Sa valeur est calculée à partir des
propriétés principal, interestRate et years. Par conséquent, pour utiliser ce composant, on
doit attribuer des valeurs à ces trois propriétés, puis lire les résultats dans la propriété future-
Value. Consultons la page JSP qui va prendre en charge le formulaire. On doit tout d’abord
créer une référence au composant CompoundInterestBean.
<%@page import="com.taglib.wdjsp.components.*"%>
<jsp:useBean id="calculator" class="CompoundInterestBean"/>
Dans le corps de la balise <jsp:useBean>, on doit faire correspondre chacune des propriétés de
configuration aux données appropriées des champs du formulaire. La balise <jsp:setPro-
perty> recherche un paramètre de requête qui est apparentée à la valeur spécifiée dans
l’attribut param de la balise. Si elle en trouve un, elle demande au JavaBeans d’affecter cette
valeur à la propriété correspondante, via l’attribut property, en effectuant les conversions
nécessaires. On ajoute alors les trois lignes suivantes à la balise <jsp:useBean> :
<jsp:setProperty name="calculator" property="principal" param="principal"/>
<jsp:setProperty name="calculator" property="interestRate"
param="interestRate"/>
<jsp:setProperty name="calculator" property="years" param="years"/>
L’attribut param de la balise <jsp:setProperty> est l’équivalent de la scriptlet JSP
<%request.getParameter("truc") %>. Le bloc de code précédent est donc fonctionnellement
Les pages JSP : une approche orientée composants
CHAPITRE 5
21

équivalent au bloc suivant qui utilise les scriptlets au lieu de l’attribut param pour initialiser les
valeurs du composant :
<jsp:setProperty name="calculator" property="principal"
value='<%= request.getParameter("principal") %>'/>
<jsp:setProperty name="calculator" property="interestRate"
value='<%= request.getParameter("interestRate") %>'/>
<jsp:setProperty name="calculator" property="years"
value='<%= request.getParameter("years") %>'/>
Lorsqu’une requête provient du formulaire, les valeurs spécifiées par l’utilisateur vont être
affectées aux propriétés du composant. Comme c’est là le moyen usuel de les configurer dans
les JSP, des raccourcis ont été fournis. Ainsi, si le nom de la propriété est le même que celui
du paramètre transmis au moyen du formulaire, on peut supprimer l’attribut param. Par consé-
quent, le corps de la balise <jsp:useBean> peut être simplifié de la façon suivante :
<jsp:setProperty name="calculator" property="principal"/>
<jsp:setProperty name="calculator" property="interestRate"/>
<jsp:setProperty name="calculator" property="years"/>
Lorsque plusieurs noms de champs du formulaire correspondent directement aux propriétés
du composant, on peut également utiliser le caractère de remplacement « * » au lieu du nom
de la propriété. L’utilisation d’un caractère de remplacement indique que l’on souhaite attri-
buer une valeur à toute propriété du composant dont le nom correspond à celui du paramètre
de la requête. Les noms doivent parfaitement correspondre pour éviter que les paramètres ne
soient reliés à des propriétés de noms différents lorsque le caractère de remplacement est
utilisé. Un paramètre de requête est recherché pour chaque propriété. Les paramètres super-
flus sont ignorés, bien qu’ils soient accessibles par les scriptlets et l’objet implicite request.
Bien entendu, on peut faire usage de commandes <jsp:setProperty> pour accéder à n’importe
quel paramètre de la requête dont le nom ne correspond pas directement à une propriété du
composant. On ne dispose d’aucun moyen pour déterminer ou spécifier l’ordre dans lequel les
propriétés sont modifiées. S’il y a des interdépendances, on préfère leur affecter explicitement
des valeurs en spécifiant une balise <jsp:setProperty> pour chacune des propriétés. Si l’on
fait soigneusement correspondre tous les noms de champ du formulaire avec les noms de
propriétés du composant, on va pouvoir configurer toutes les propriétés avec une seule
instruction en utilisant un caractère de remplacement :
<jsp:setProperty name="calculator" property="*"/>
Une fois que le JavaBeans est configuré, on peut lire les résultats des calculs du composant
dans la propriété futureValue. On peut également vérifier les données d’entrée en consultant
les valeurs des propriétés que l’on vient de configurer.
Si vous investissez $<jsp:getProperty name="calculator" property="principal"/>
pour <jsp:getProperty name="calculator" property="years"/> années
à un taux d’intérêt de
<jsp:getProperty name="calculator" property="interestRate"/>%
mensuellement composé, vous obtiendrez
$<jsp:getProperty name="calculator" property="futureValue"/>
Les sorties du programme JSP de prise en charge du formulaire vont produire les résultats
suivants :
JSP – Java Server Pages
22

Listing 5-2. CompoundInterestResults.jsp


<%@ page import="com.taglib.wdjsp.components.CompoundInterestBean" %>
<jsp:useBean id="myBean" class="CompoundInterestBean"/>
<jsp:setProperty name="calculator" property="principal"/>
<jsp:setProperty name="calculator" property="years"/>
<jsp:setProperty name="calculator" property="interestRate"/>
</jsp:useBean>
<html>
<body>
Si vous investissez $<jsp:getProperty name="calculator" property="principal"/>
pour <jsp:getProperty name="calculator" property="years"/> années avec un taux
d’intérêt de <jsp:getProperty name="calculator" property="interestRate"/>%
mensuellement composé, vous obtiendrez
$<jsp:getProperty name="calculator" property="futureValue"/>
</body>
</html>
Les JSP ne font pas la différence entre des requêtes GET et POST pour la soumission des formu-
laires. On peut aussi utiliser des éléments cachés du formulaire pour ajouter des informations
de configuration sans obliger l’utilisateur à les saisir. On peut également coder directement
des directives dans l’URL de la requête en suivant les conventions normalisées de codage
d’URL. Par exemple, l’URL suivante va calculer les intérêts sans faire appel à un formulaire :
http://host/InterestCalculator.jsp?interest=0.10&years=15&principal=1000
Les propriétés dans l’URL sont exactement les mêmes que celles que l’on peut obtenir d’un
formulaire en utilisant la méthode GET pour la transmission des données. Bien entendu, il
faudra recourir à des caractères d’échappement pour tous les caractères spéciaux, mais ils
n’auront pas à être décodés dans les pages JSP car le conteneur de JSP le fait automatique-
ment. Quant aux valeurs du formulaire, quelques précautions sont à prendre : gardez-vous de
confier aux champs de formulaires, même cachés, des informations confidentielles, telles que
des mots de passe de base de données. En effet, les champs de données d’un formulaire
HTML, qu’ils soient cachés ou non, peuvent être visualisés assez facilement en affichant le
source de la page HTML qui contient les données du formulaire. Il est plus judicieux, dans ce
cas, d’enregistrer les informations sensibles dans nos pages JSP comme partie intégrante
d’une balise de composant ou de scriptlets JSP, car ces données vont être traitées au niveau du
serveur et ne seront jamais visibles par le client.

AVERTISSEMENT On ne peut pas utiliser des paramètres de requête commençant par java, javax et com.sun. Ils sont
réservés à l’utilisation propre du conteneur de JSP et peuvent entrer en conflit avec les paramètres affec-
tés aux requêtes par le conteneur.

Spécifications des valeurs d’initialisation par défaut


Si on essaie d’initialiser une propriété de composant à partir d’un paramètre de requête qui
n’existe pas ou qui est défini comme une valeur vide, la commande <jsp:setProperty> n’aura
aucun effet. La valeur null n’est pas affectée à la propriété et la balise <jsp:setproperty> est
simplement ignorée. On peut fournir une valeur par défaut pour une propriété en affectant
d’abord explicitement cette dernière, puis en essayant de le faire à partir de la requête :
<jsp:setProperty name="calculator" property="interestRate" value="0.10"/>
<jsp:setProperty name="calculator" property="interestRate" param="interestRate"/>
Les pages JSP : une approche orientée composants
CHAPITRE 5
23

Dans cet exemple, la valeur dix pour cent est affectée à la propriété interestRate, mais elle
peut être écrasée par la valeur du paramètre de requête interestRate s’il existe. On peut ainsi
fournir des valeurs par défaut pour les propriétés critiques et créer des pages flexibles, accessibles
de plusieurs façons différentes.

La sécurité
La notation utilisant les caractères de remplacement introduite auparavant, <jsp:setProperty
property="*">, est un raccourci très puissant pour initialiser les propriétés d’un composant à
partir d’une requête, en particulier pour faire correspondre des valeurs entrées dans un formu-
laire aux propriétés correspondantes d’un composant. Mais il faut utiliser ces abréviations
avec prudence lorsque les propriétés du composant contiennent des informations sensibles,
car il est très facile à un utilisateur de construire ses propres requêtes.
Considérons par exemple une application bancaire en ligne qui manipule des informations sur
les comptes via une classe JavaBeans nommée AccountBean. Cette classe fournit des
propriétés pour accéder à des informations qui concernent le compte, telles que le numéro du
compte (accountNumber) et le solde (balance), ainsi que des propriétés correspondant aux
transactions sur ces comptes, telles que le retrait d’une somme d’argent (withdrawalAmount) et
le transfert d’une somme d’argent (transferAmount). Comme le formulaire permet à un utili-
sateur de spécifier un retrait, il va pointer sur la page JSP, comme cela est illustré ci-après, qui
effectue la transaction (par effet de bord de l’affectation de valeurs aux propriétés) et retourne
le résultat :
<jsp:useBean id="myAccount" class="AccountBean">
<jsp:setProperty name="myAccount" property="*"/>
</jsp:useBean>
<html>
<head><title>retrait d’argent</title></head> <body>
<p>
un retrait de $<jsp:getProperty name="myAccount" property="withdrawalAmount"/>
a été effectué sur le compte
#<jsp:getProperty name="myAccount" property="withdrawalAmount"/>.
Le solde actuel de votre compte est $<jsp:getProperty name="myAccount"
➥property="balance"/>.
Nous vous remercions de votre confiance.
Au premier abord, le code semble ordinaire. Cependant, supposons que l’accès aux propriétés
du composant soit autorisé en lecture et en écriture, ce qui est proche de la réalité. Soit
retrait.jsp, l’URL de cette page. Examinons l’effet produit par la requête utilisateur suivante :
http://server/account/withdraw.jsp?accountNumber=Phil31N&balance=1000000
En principe, on va accéder à cette page en tant qu’élément cible d’un formulaire, mais rien
n’empêche l’utilisateur de construire manuellement sa propre requête. Le montant du retrait
n’est pas spécifié dans cette URL, ce n’est probablement pas un problème, mais la présence
d’un paramètre de requête appelé solde est très ennuyeux. Lorsque le conteneur de JSP traite
la balise <jsp:setProperty>, il va associer ce paramètre à une propriété du JavaBeans portant
le même nom et va essayer de lui affecter la valeur $1 000 000 !
Il faut espérer que le développeur Java, responsable de l’implémentation de AccountBean, a
mis des protections pour empêcher ce type de falsification, mais cette vigilance doit être plus
importante lorsque des caractères de remplacement sont utilisés. Si le JavaBeans possède des
JSP – Java Server Pages
24

propriétés accessibles en écriture et dont l’accès doit être contrôlé (le solde d’un compte
bancaire, par exemple), alors ce JavaBeans doit effectuer lui-même les contrôles d’accès. En
l’absence d’un tel contrôle, le JavaBeans peut se laisser abuser par des requêtes malveillantes
comme celle que l’on vient de décrire, surtout lorsqu’elles sont combinées avec des balises
<jsp:setProperty> utilisant des raccourcis tels que les caractères de remplacement.

3.4. Contrôle de la portée d’un JavaBeans


Jusqu’ici, on a traité de l’utilisation des JavaBeans pour encapsuler des données ou un
comportement pendant la durée de vie d’une seul page. Chaque fois que la page est demandée,
une nouvelle instance du JavaBeans est créée et éventuellement modifiée via les balises
<jsp:setProperty>. Les JSP sont toutefois dotées d’une fonctionnalité puissante qui permet
de préciser si un JavaBeans doit continuer à exister au-delà d’une seule requête de page. De
tels JavaBeans sont mémorisés au niveau du serveur et réutilisés dans plusieurs pages ou dans
plusieurs requêtes pour la même page. Cette possibilité permet de créer un JavaBeans une
seule fois et puis d’y accéder pendant toute la durée de la visite du site par un utilisateur.
Toutes les propriétés auxquelles on a affecté des valeurs persistent pendant toute la durée de
vie du JavaBeans.

Accessibilité d’un JavaBeans et durée de vie


L’accessibilité et la durée de vie d’un JavaBeans sont contrôlées via l’attribut scope de la
balise <jsp:useBean>. Cet attribut peut avoir page, request, session ou application comme
valeurs. C’est par l’accessibilité d’un JavaBeans que l’on détermine les pages et les parties
d’une application web qui peuvent avoir accès au JavaBeans et à ses propriétés. La durée de
vie d’un JavaBeans détermine sa période d’existence avant qu’il ne soit plus accessible. Un
récapitulatif des effets de la portée d’une valeur sur l’accessibilité et la durée de vie d’un Java-
Beans est présenté dans le tableau 5-4.

Tableau 5-4. Les portées possibles d’un JavaBeans

Portée Accessibilité Durée de vie


page Page courante uniquement Jusqu’à ce que la page soit affichée ou que
le contrôle soit transféré à une nouvelle page
request Page courante et toute page incluse ou transférée Jusqu’à la fin du traitement de la requête et
la réponse renvoyée à l’utilisateur
session La requête courante et toute requête ultérieure La durée de vie de la session de l’utilisateur
apparaissant dans la même fenêtre du navigateur
application La requête courante et toutes celles à venir qui La durée de vie de l’application
font partie de la même application web

Lorsqu’un JavaBeans est créé au niveau du serveur afin qu’il soit réutilisé dans plusieurs
pages, il est identifié par un nom spécifié par l’attribut id de la balise <jsp:useBean>. Chaque
fois que l’on essaie de créer un JavaBeans avec la balise <jsp:useBean>, le serveur va recher-
cher dans sa mémoire un JavaBeans qui porte le même id que celui qui est spécifié dans la
balise. S’il en trouve un, et qu’il est accessible depuis la requête courante, alors, plutôt que
d’en créer un autre, le JavaBeans est utilisé. Si des commandes de configuration ont été spéci-
fiées dans la balise, elles vont être ignorées parce que le JavaBeans a déjà été initialisé. La
Les pages JSP : une approche orientée composants
CHAPITRE 5
25

syntaxe de l’attribut scope est présentée ci-après. Un JavaBeans ne peut avoir qu’une seule
valeur de portée. On ne peut pas les combiner dans la mesure où elles sont par définition
mutuellement exclusives.
<jsp:useBean id="beanName" class="class"
scope="page|request|session|application"/>

Les JavaBeans de portée page


Si l’on ne spécifie pas une portée pour un composant JavaBeans au moment de sa création
avec la balise <jsp:useBean>, une portée de niveau page lui est affectée par défaut. Un compo-
sant JSP ayant cette portée est le moins accessible et cela correspond à la durée de vie la plus
courte. Chaque fois qu’une page est demandée, par un visiteur nouveau ou qui revient, une
instance du JavaBeans est créée. Si des balises d’initialisation ou des scriptlets sont présentes
dans la balise, elles seront exécutées à chaque fois.
Il est donc important de retenir que les JavaBeans qui ont une portée page sont temporaires ;
ils ne persistent pas entre les requêtes. Voilà pourquoi ils ne sont pas accessibles en dehors de
la page. Si on utilise les balises <jsp:include> et <jsp:forward>, tous les JavaBeans ayant une
portée page ne seront pas disponibles pour la page nouvelle ou incluse. Si une page référencée
par une de ces balises contient des balises <jsp:useBean> qui spécifient un JavaBeans ayant le
même id que le composant créé dans la page mère, ces dernières vont ignorer le JavaBeans
initial, parce qu’il est hors de portée pour créer une nouvelle instance. Il faut noter que les
deux balises suivantes sont identiques puisque la portée par défaut est la page :
<jsp:useBean id="bean1" class="com.manning.jsp.ClockBean"/>
<jsp:useBean id="bean2" class="com.manning.jsp.ClockBean scope="page"/>
Si le JavaBeans n’a aucune raison de perdurer entre les requêtes ou si les informations qu’il
contient ne sont plus d’aucune utilité une fois la requête traitée, il est évident qu’il faut lui
affecter une portée page. Par exemple, si notre ClockBean est initialisé avec l’heure et la date
courantes la première fois qu’il a été créé, il n’est pas nécessaire de le conserver très longtemps.
Cependant, si on utilise les balises <jsp:include> et <jsp:forward>, on doit augmenter la portée
de notre JavaBeans au niveau requête pour qu’il puisse être accessible par ces autres pages.

Les JavaBeans de requête


Si l’on spécifie une valeur request pour l’attribut de portée de la balise <jsp:useBean>, le
conteneur de JSP va essayer de récupérer le JavaBeans de la requête elle-même. Comme le
protocole HTTP ne fournit pas de mécanisme qui permette au navigateur de mémoriser autre
chose que des couples simples (nom, valeur) dans la requête, un JavaBeans ne peut être enre-
gistré dans la requête que par une servlet ou une autre page JSP sur le serveur. Le JavaBeans
y sera alors mémorisé sous forme d’attributs de requêtes, une fonctionnalité de l’API de Java
Servlet version 2.2 que l’on verra au chapitre 8. Si le JavaBeans n’a pas été trouvé initiale-
ment dans la requête, il va être créé et y être placé.
La durée de vie d’un JavaBeans qui a une portée de requête est la même que s’il avait une
portée de page à ceci près que son accessibilité est étendue aux pages référencées dans les
balises <jsp:include> et <jsp:forward>. De cette façon, l’utilité de la portée de requête est
double. Tout d’abord, elle permet d’utiliser les servlets Java pour créer un JavaBeans, et de le
transmettre à notre page JSP. Ensuite, elle donne la possibilité d’étendre le champ d’action de
notre JavaBeans aux pages incluses dans, ou transmises, depuis la page initiale.
JSP – Java Server Pages
26

Considérons par exemple une situation où l’on introduit un pied de page via la balise
<jsp:include> et dans laquelle on souhaite introduire des données spécifiques à chaque page.
Si on place les données dans la portée page, elles ne seront pas accessibles par le pied de page
qui a été inclus. Pour y parvenir, il faut enregistrer nos informations dans un JavaBeans qui a
une portée request, ce qui permet à nos données d’être visibles par le pied de page et par la
page courante. Dans cet exemple, on associe, à chaque page, le nom d’une personne à
contacter qui apparaît dans le pied de page.
<jsp:useBean id="contact" class="jsp.ContactBean" scope="request">
<jsp:setProperty name="contact" property="name" value="Kris DeHart"/>
</jsp:useBean>
<html>
<body>
Bienvenue dans votre site!
<jsp:include file="/footers/standardFooter.jsp" flush="true"/>
</body>
</html>
Dans cet exemple, contact est accessible par la page courante et par standardFooter.jsp, qui
est un extrait de HTML ressemblant à ceci :
<HR>
Pour toute modification de requête, contactez
<jsp:getProperty name="contact" property="name"/>
Cet exemple de conception d’une page par introduction de petites pages de composants pour
en construire une, composée, plus grande, est une technique très utile pour la conception de
pages complexes. On détaillera ce procédé au chapitre 8.

Les JavaBeans de session


La portée de niveau session introduit la persistance des composants dans les JSP, et constitue
l’une de ses constructions les plus puissantes. Contrairement aux portées de requêtes et de
pages, un JavaBeans ayant session comme valeur de l’attribut de portée doit perdurer au-delà
de la durée de vie d’une seule requête, parce qu’il est placé dans l’objet de session de l’utili-
sateur. Au chapitre 2, dans notre discussion sur la gestion de sessions, on a vu que le
conteneur de JSP maintient un objet de session unique pour chaque utilisateur visitant le site.
Le fait de placer un JavaBeans dans une portée session provoque l’enregistrement de cet objet
de session qui sera identifié par la valeur de l’attribut id.
Il n’est requis rien de particulier du JavaBeans pour qu’il supporte une telle persistance. En
effet, le conteneur de JSP va lui-même prendre en charge la gestion de l’état chaque fois que
l’on place un JavaBeans dans une session via l’attribut scope. Lorsqu’un Bean est enregistré
dans la session d’un utilisateur, il devient accessible à toutes les autres pages JSP sur le
serveur. Si on fait appel avec une balise <jsp:useBean> à un JavaBeans qui existe déjà dans la
session, l’identificateur que l’on spécifie va faire référence à l’instance existante du Java-
Beans, et l’appel n’entraînera pas la création d’un nouveau JavaBeans.
La durée de vie d’un JavaBeans de session est déterminée par le conteneur de JSP et est
estimée en minutes, heures ou jours. Certains conteneurs de JSP, tels que WebSphere d’IBM,
peuvent enregistrer les données de session sur disque lorsque le serveur tombe en panne, et
restaurent les sessions à la reprise. Un conteneur muni d’une telle aptitude accorde à un Java-
Beans une durée de vie infinie. Cependant, tous les conteneurs ne peuvent pourvoir à un tel
Les pages JSP : une approche orientée composants
CHAPITRE 5
27

comportement. Il est donc déconseiller de faire cette hypothèse. Si l’on a besoin d’enregistrer
des informations pour un temps indéterminé, ou bien si la session est utilisée pour mémoriser
des données sensibles, mieux vaut enregistrer ses données dans une base de données. En effet,
la plupart des conteneurs mettent fin aux données de session si on n’y a pas accédé au bout de
quelques heures.

ASTUCE Si on a utilisé <%@ page session="false" %> pour indiquer que la page ne s'exécute pas dans un
contexte de session, on sera dans l'incapacité de rendre des composants JavaBeans persistants en utili-
sant la session courante. La valeur par défaut de l'attribut de session est true, activant ainsi le support
de session. Cependant, si ce support ne vous est d'aucune utilité, il faut affecter à cet attribut la valeur
false pour éviter que le conteneur de servlets ne crée des objets de session inutiles et gourmands en
mémoire.

Les sessions sont importantes quand il s’agit d’enregistrer des informations collectées
pendant la visite du site par un utilisateur et de récupérer des informations souvent utiles au
niveau de la page. Elles peuvent être utilisées pour transférer des informations d’une page à
une autre, sans que chacune d’elle ne doive inclure un programme ou un temps de traitement
supplémentaire pour accéder à des informations enregistrées dans une base de données ou une
source externe. Le caddie des achats est un bon exemple de données orientées session. L’utili-
sateur va souhaiter que le contenu du caddie soit accessible tout au long de l’application. On
va donc créer le JavaBeans ShoppingCartBean qui représente le caddie des achats, et l’enregis-
trer dans la session de l’utilisateur. Dans chaque page, on peut introduire une référence au
caddie qui permet d’afficher le total des achats en cours si on le souhaite.
On va voir, de la façon la plus simple qui soit, comment on peut utiliser le JavaBeans Timer-
Bean pour savoir pendant combien de temps une session utilisateur a été active. On peut
utiliser un tel JavaBeans pour déconnecter un individu qui est resté inactif pendant une
certaine période, ou pour enregistrer des visites pour lesquelles la durée est un paramètre
important, comme la réalisation en ligne d’une synthèse ou d’un examen. Notre TimerBean
possède une fonction de base : rendre compte du temps passé entre le moment de sa création
et le temps courant. Ce JavaBeans, que l’on approfondira au chapitre 6, possède les propriétés
présentées dans le tableau 5-5.

Tableau 5-5 Les propriétés de TimerBean

Nom Type d’accès Type Java Exemple


ellapsedMillis lecture uniquement long 180000
ellapsedSeconds lecture uniquement long 180
elapsedMinutes lecture uniquement long 3
startTime lecture, écriture long 857374234

La propriété startTime est supposée fournir un moyen pour affecter la valeur de la date au
démarrage du JavaBeans, soit en lui attribuant une valeur de date particulière (exprimée en
millisecondes depuis la date 0), soit la date courante en lui transmettant une valeur nulle ou
négative.
JSP – Java Server Pages
28

Voici un exemple utilisant ce JavaBeans qui, au premier chargement, initialise l’heure et


affiche le temps écoulé pour chacun des chargements ultérieurs (en supposant bien entendu
que la durée entre deux visites ne dépasse pas la valeur du délai accordée à une session du
conteneur de JSP).
<%@ page import="com.taglib.wdjsp.components.*" %>
<jsp:useBean id="timer" class="TimerBean" scope="session"/>
<html>
<body>
Temps écoulé :
<jsp:getProperty name="timer" property="elapsedMinutes"/> minutes
</body>
</html>
Si on souhaite ajouter cette fonctionnalité à l’ensemble des pages, on doit introduire les
balises de JavaBeans appropriées dans leur propre fichier, que l’on appellera ensuite avec la
balise <jsp:include>. Cet exemple, que l’on a récupéré dans un jeu de question/réponse en
temps réel (quiz) sur le Web, utilise via un fichier inclus le JavaBeans TimerBean pour afficher
le temps écoulé dans le pied de chaque page.
<html>
<body>
<form action="/servlet/processQuestions/6">
<b>Question 6</b><br>
Quelle est la vitesse de croisière d’une hirondelle d’Europe ?
<br> <input type="text" name="answer">
<br> <input type="submit" value="Submit Answer">
</form>
<jsp:include page="/footers/ElapsedTimeFooter.html" flush="true"/> </body>
</html>
Voici le contenu du fichier ElapsedTimedFooter.html :
<%@ page import="com.taglib.wdjsp.components.*" %>
<jsp:useBean id="timer" class="TimerBean" scope="session"/>
<hr>
N’oubliez pas que la rapidité de réponse est prise en compte!
<BR>
Temps utilisé :
<jsp:getProperty name="timer" property="elapsedSeconds"/>
secondes
On peut également utiliser plusieurs instances différentes de TimerBean qui s’exécutent en
même temps, à condition que leurs identificateurs soient différents. C’est l’attribut id de la
balise <jsp:useBean> qui permet de distinguer les diverses instances d’un JavaBeans, qu’il soit
référencé dans la page ou recherché dans la session.

ASTUCE La durée de vie par défaut d’une session est déterminée par le conteneur de JSP (ou plus précisément,
par le conteneur de servlets). Nouvellement introduites dans la version 2..2 de Servlet API, les méthodes
getMaxInactiveInterval() et setMaxInactiveInterval() de l’interface HttpSession peuvent être
utilisées pour visualiser ou mettre à jour les variables d’expiration. La méthode getLastAccessdTime()
de cette interface permet de connaître le temps écoulé depuis le dernier accès aux données de la
session.
Les pages JSP : une approche orientée composants
CHAPITRE 5
29

Les JavaBeans d’application


Un JavaBeans de portée application possède un cycle de vie et une accessibilité plus impor-
tants qu’un JavaBeans de session. Les JavaBeans qui ont cette portée sont associés à une
application JSP particulière sur le serveur. Une application JSP est une collection de pages
JSP ou HTML, d’images, d’applets ou d’autres ressources qui sont regroupées sous une
certaine hiérarchie d’URL. La durée de vie des JavaBeans d’application perdurent au long de
l’existence du conteneur de JSP, ce qui veut dire qu’ils ne sont pas récupérés jusqu’à l’arrêt du
serveur, qu’ils n’expirent pas après quelques heures ou quelques jours. Contrairement aux
JavaBeans de session qui ne sont accessibles que pour les requêtes ultérieures d’un utilisateur
donné, les JavaBeans d’application sont partagés par tous les utilisateurs de l’application qui
lui sont associés. Toute page JSP qui fait partie de l’application peut avoir accès aux Java-
Beans d’application créés par d’autres pages dans cette application. On verra au chapitre 10
comment créer ces applications JSP packagées.
La portée application est utilisée pour enregistrer des informations utiles tout au long de
l’application et qui ne sont pas spécifiques à des pages précises ayant demandé l’accès au
JavaBeans. Une fois le JavaBeans placé dans une portée d’application, il peut être utilisé par
toutes les pages du site. Si le JavaBeans nécessite une donnée de configuration, il doit être
indépendant de la page. Une portée d’application n’est sûrement pas appropriée à un Java-
Beans, si l’on s’attend à ce que les données de configuration changent d’une requête de page
à une autre ou d’un utilisateur à un autre.
Lorsqu’un JavaBeans est enregistré avec la portée application, il n’existera qu’une instance
de ce composant par serveur. Il faut être prudent quand on veut effectuer des modifications de
propriétés d’un JavaBeans une fois qu’il a été enregistré dans l’application : tout changement
que l’on peut apporter aux propriétés va immédiatement avoir une incidence sur toutes les
pages qui référencent ce JavaBeans
L’aptitude de la portée application à garder en mémoire cache les informations relatives à
l’application qui seraient trop coûteuses à générer pour chaque requête de page est aussi parti-
culièrement intéressante. On peut par exemple mentionner que toutes les pages d’un catalogue
en ligne requièrent des accès à une table comprenant les forfaits de livraison. Cette informa-
tion peut être encapsulée dans un JavaBeans et placée dans une portée d’application. Cela
signifie que les données ne vont être récupérées qu’une seule fois dans la base de données,
économisant ainsi le temps d’accès à la base et à la mémoire du serveur. Le JavaBeans ne se
référencera plus comme à l’ordinaire ; s’il n’a pas encore été instancié et placé dans la session,
le serveur va le prendre en charge :
<jsp:useBean id="ship" class="ShipRateBean" scope="application"/>
<html>
<body>
Les frais de livraison actuels sont :
<jsp:getProperty name="ship" property="baseCharge"/>
par livraison plus
<jsp:getProperty name="ship" property="perItemCharge"/>
pour chaque produit livré.
</body>
</html>
S’il faut configurer le JavaBeans, on doit utiliser le corps de la balise <jsp:useBean> pour attri-
buer les valeurs initiales aux propriétés. Comme on doit effectuer cette initialisation pour
JSP – Java Server Pages
30

chacune des pages des utilisateurs, on va probablement s’enquérir d’une autre solution. Tout
d’abord, on peut utiliser des JavaBeans spécifiques aux applications qui ne nécessitent pas de
configuration particulière ou dont les constructeurs collectent les informations de configura-
tion à partir d’une autre source (un fichier de propriétés, par exemple). Ensuite, on peut
procéder par étapes pour s’assurer que le JavaBeans en question est bien placé dans une portée
d’application avant que les pages qui en dépendent ne veuillent y accéder. Ou encore, on peut
organiser une suite de JavaBeans préconfigurés sur disque et les restaurer quand cela est
nécessaire.

L’attribut type et la portée


En général, l’attribut type de la balise <jsp:useBean> n’est utilisé que pour manipuler des
JavaBeans qui sont censés être dans la portée et qui sont des sous-classes d’une certaine classe
de base de plus haut niveau. Si le JavaBeans existe dans la portée courante (une portée de
session ou de requête), et que l’on ne peut recourir à aucun moyen pour connaître son type, on
peut tout simplement préciser sa classe de base via l’attribut type. Par exemple, si une servlet
ou une page JSP a placé une collection d’objets dans notre session, on sait que ces objets sont
dérivés de l’interface Collection de Java, mais il ne nous est pas possible de savoir si les
autres pages utilisent, par exemple, List, Set ou ListArray. Dans ce cas, comme il n’y a
aucune utilité à spécifier une classe, on référence simplement l’interface commune Collection
comme type du JavaBeans :
<jsp:useBean id="elements" type="java.util.Collection" scope="session" />

Vous aimerez peut-être aussi