Vous êtes sur la page 1sur 52

JavaServer Faces - JSF

Chapitres traits Introduction JSF


Pour afficher graphiquement les informations provenant du serveur, nous avons besoin d'une interface utilisateur. Les
applications utilisant les interfaces pour interagir avec l'utilisateur sont de diffrents types : applications de bureau, applications
web s'excutant dans un navigateur ou applications mobiles sur un terminal portable. Nous nous intressons ici sur les
interfaces web.
Initialement, le World Wide Web tait un moyen de partager des documents crits en HTML. Le protocole HTTP a t conu pour
vhiculer ces documents, qui taient l'origine essentiellement statiques (leur contenu n'voluait pas beaucoup au cours du
temps).
1. Les pages statiques sont composes de HTML pur contenant ventuellement des graphiques eux aussi statiques (JPG, PNG, par exemple).
2. Les pages dynamiques sont en revanche composes en temps rel ( la vole) partir de donnes calcules partir d'informations fournies par l'utilisateur.
Pour crer un contenu dynamique, il faut analyser les requtes HTTP, comprendre leur signification et crer des rponses dans un format que le navigateur saura
traiter. Les servlets simplifie le processus en fournissant une vue oriente objet du monde HTTP (HttpRequest, HttpResponse, etc.).
Cependant, le modle des servlets tait de trop bas niveau et c'est la raison pour laquelle, les pages JSP (JavaServer Pages) ont ensuite pris le relais pour
simplifier la cration des pages web dynamiques. En coulisse, une JSP est une servlet, sauf qu'elle est crite essentiellement en HTML - avec un peu de Java
pour effectuer les traitements.
Ceci dit, les servlets peuvent toujours tre utiles dans le cas de traitements spcifiques qui ne consistent pas crer, pour la rponse au navigateur, de page web
en format HTML. Nous pourrions, par exemple, fabriquer une vignette correspondant une photo grand format archive sur le serveur.
JSF (JavaServer Faces, ou simplement Faces) a t cr en rponse certaines limitations de JSP et utilise un autre modle consistant porter des composants
graphiques vers le Web. Inspir par le modle Swing, JSF permet aux dveloppeurs de penser en termes de composants, d'vnements, de beans grs et de
leur interactions plutt qu'en termes de requtes, de rponses et de langages marqueurs.
Son but est de faciliter et d'acclrer le dveloppement des applications web en fournissant des composants graphiques (comme des zones de texte, les listes, les
onglets, les grilles, etc.) afin d'adopter une approche RAD (Rapid Application Development).
Introduction JSF
Les applications JSF sont des applications web classiques qui interceptent HTTP via la servlet Faces et produisent du HTML.
En coulisse, cette architecture permet de greffer n'importe quel langage de dclaration de page (PDL), de l'afficher sur des dispositifs diffrents (navigateur web,
terminaux mobiles, etc.) et de crer des pages au moyen d'vnements, d'couteurs et de composants, comme en Swing.
JSF fournit un ensemble de widgets standard (boutons, liens hypertextes, cases cocher, zone de saisie, tableaux dynamiques, etc.) et facilite son extension par
l'ajout de composants tiers.
La figure ci-dessous reprsente les parties les plus importantes de l'architecture JSF qui la rendent aussi riche et aussi souple :
1. FacesServlet : est la servlet principale de l'application qui sert de contrleur. JSF utilise le patron de conception MVC (Modle-Vue-Contrleur).
MVC permet de dcoupler la vue (la page) et le modle (le traitement des donnes affiches dans la vue). Le contrleur prend en charge les actions
de l'utilisateur qui pourraient impliquer des modifications dans le modle et dans les vues. Avec JSF, ce contrleur est la servlet FacesServlet.
Toutes les requtes de l'utilisateur passent sytmatiquement par elle, qui les examine et appelle les diffrentes actions correspondantes du modle
en utilisant les beans grs. Il est possible de configurer le comportement de cette servlet au travers d'annotations spcifiques (sur les beans grs,
les convertisseurs, les composants, les moteurs de rendu et les validateurs).
2. Pages et composants : Le framework JSF doit envoyer une page sur le dispositif de sortie du client (un navigateur, pas exemple) et exige donc une
technologie d'affichage appele PDL. Dans sa version la plus rcente, JSF utilise plutt les Facelets. Facelets est forme d'une arborescence de
composants (galement appels widgets ou contrles) fournissant des fonctionnalits spcifiques pour interagir avec l'utilisateur (champ de saisie,
boutons, liste, etc.).
JSF dispose d'un ensemble standard de composants (graphiques ou sans apparences visuelles) et permet de crer galement facilement
les vtres (composants personnaliss). Pour grer cette arborescence, une page passe par un cycle de vie complexe (initialisation,
vnements, affichage, etc.).
Le code ci-dessous correspond la page web de conversion vue plus haut et reprsente une page Facelets en XHTML qui utilise les
marqueurs xmln:h et xmlns:f pour afficher un formulaire avec les deux zones de saisies (uro et Franc) et un bouton (pour la conversion).
Cette page est compose de plusieurs composants JSF : certains n'ont pas d'apparence visuelle, comme ceux qui dclare l'en-tte
<h:head>, le corps <h:body> ou le formulaire <h:form>. D'autres ont une reprsentation graphique et affichent un texte en sortie
<h:outputText>, une zone de saisie <h:inputText> ou un bouton <h:commandButton>. Vous remarquez que nous pouvons galement
utiliser des marqueurs HTML purs : <html>, <h3>, <hr />.
3. Moteurs de rendu : JSF reconnait deux modles de programmation pour afficher les composants : l'implmentation directe et l'implmentation
dlgue. Avec le modle direct, les composants doivent eux-mme s'encoder vers une reprsentation graphique et rciproquement. Avec le mode
dlgu, ces oprations sont confies un moteur de rendu, ce qui permet aux composants d'tre indpendants de la technologie d'affichage
(navigateur, terminal mobile, etc.) et donc d'avoir plusieurs reprsentations graphiques possibles.
Un moteur de rendu s'occupe d'afficher un composant et de traduire la saisie d'un utilisateur en valeur de composants. Nous pouvons
donc le considrer comme un traducteur plac entre le client et le serveur : il dcode la requte de l'uilisateur pour initialiser les valeurs
du composant et encode la rponse pour crer une reprsentation du composant que le client pourra comprendre et afficher.
4. Convertisseurs et validateurs : Lorsque la page est affiche, l'utilisateur peut s'en servir pour entrer des donnes. Comme il n'y a pas de contraintes
sur les types, un moteur de rendu ne peut pas prvoir l'affichage de l'objet. Voil pourquoi les convertisseurs existent : ils traduisent un objet
(Integer, Date, Enum, Boolean, etc.) en chane de caractres afin qu'il puisse s'afficher (protocole HTTP est un protocole uniquement textuel) et,
inversement, construisent un objet partir d'une chane qui a t saisie. JSF fournit un ensemble de convertisseurs pour les types classiques dans la
paquetage javax.faces.convert, mais vous pouvez dvelopper les vtres ou ajouter des types provenant de tierces parties.
Parfois, les donnes doivent galement tre valides avant d'tre traites par le back-end : c'est le rle des validateurs ; nous pouvons ainsi
associer un ou plusieurs validateurs un composant unique afin de garantir que les donnes saisies sont correctes. JSF fournit quelques
validateurs (LengthValidator, RegexValidator, etc.) et vous permet d'en crer d'autres en utilisant vos propres classes annotes. En cas
d'erreur de conversion ou de validation, un message est envoy dans la rponse afficher.
5. Beans grs et navigation : Tous les concepts que nous venons de prsenter - qu'est-ce qu'une page, qu'est-ce qu'un composant, comment sont-il
affichs convertis et valids - sont lis une page unique, mais les applications web sont gnralement formes de plusieurs pages et doivent
raliser un traitement mtier (en appelant une couche EJB, par exemple). Le passage d'une page une autre, l'invocation d'EJB et la
synchronisation des donnes avec les composants sont pris en charge par les beans grs.
L'exemple ci-dessous visualise un projet d'entreprise de gestion complte d'une bibliothque. Nous dcouvrons ainsi toute la partie mtier au travers
d'un certain nombre d'EJB session, comme GrerAuteurs, GrerLivres, etc. qui s'occupent galement de la persistance l'aide d'entits adaptes. La
couche prsentation est traite au moyen de JSF o nous dcouvrons toute la structure interne. Tout d'abord la servlet FacesServlet qui joue le rle de
contrleur et qui prend en compte toute les requtes venant du client dport. Ensuite, la partie visuelle est reprsente par les diffrentes pages web
comme auteurs.xhtml, livres.xhtml, etc. Enfin, ce qui permet de mettre en relation la logique mtier avec cette partie visuelle, dans ce que nous
appelons le back-end, nous trouvons les beans grs comme GestionAuteurs, GestionLivres, etc.
Vous remarquez qu'un bean gr est systmatiquement associ une page xhtml. Ce n'est pas absolument indispensable. Nous pouvons tout aussi
bien avoir plusieurs beans pour une mme page et inversement, un seul bean gr peut s'occuper de plusieurs pages.
5. Un bean gr est classe Java spcialise qui synchronise les valeurs avec les composants, traite la logique mtier et gre la navigation entre les
pages. Nous associons un composant une proprit ou une action spcifique d'un bean gr en utilisant EL (Expression Language) :
Ainsi, par exemple, la premire zone de saisie lie directement la valeur du champ la proprit euro. Cette valeur est alors
automatiquement synchronise avec la proprit du bean gr.
Un bean gr peut galement traiter des vnements et associer un bouton de soumission une action spcifique. Ainsi, lorsque nous
cliquons sur la bouton de conversion, celui-ci dclenchera un vnement sur le bean gr, qui excutera alors une mthode couteur - ici,
euroFranc().
Le bean gr est une classe Java annote par @ManagedBean et possde deux proprits, euro et franc, qui sont synchronises avec les
valeurs des composants de la page. La mthode euroFranc() de ce bean manag ralise le traitement de la conversion.
6. Support d'Ajax : Une application web doit fournir une interface riche et rapide. Cette ractivit peut tre obtenue en ne modifiant que de petites
parties de la page de faon asynchrone, sans que la page ne soit recharge entirement, et c'est exactement pour cela qu'Ajax a t conu.
Par exemple, sur notre application web de conversion, nous pourrions souhaiter que seule la zone des francs soit change lors de la
soumission de la requte de conversion partir des uros :
Voici le code correspondant :
Cycle de vie
Une page JSF est une arborescence de composants avec un cycle de vie spcifique qu'il faut bien avoir compris pour savoir quel moment les composants sont
valids ou quand le modle est mis jour.
1. Un clic sur un bouton provoque l'envoi d'une requte du navigateur vers le serveur et cette requte est traduite en vnement qui peut tre trait par
l'application sur le serveur.
2. Toutes les donnes saisie par l'utilisateur passent par une tape de validation avant que le modle soit mis jour et que du code mtier soit appel.
3. JSF se charge alors de vrifier que chaque composant graphique (composants parent et fils) est correctement rendu par le navigateur.
Le cycle de vie de JSF se divise en six phases :
1. Restauration de la vue : JSF trouve la vue cible et lui applique les entres de l'utilisateur. S'il s'agit de la premire visite, JSF cre la vue comme un
composant UIViewRoot (racine de l'arborescence de composants, qui constitue une page particulire). Pour les requtes suivantes, il rcupre
l'UIViewRoot prcdemment sauvegarde pour traiter la requte HTTP courante.
2. Application des valeurs de la requte : Les valeurs fournies avec la requte (champ de saisie, d'un formulaire, valeurs des cookies ou partir des en-
ttes HTTP) sont appliques aux diffrents composants de la page. Seuls les composants UI (de la page) modifient leur tat, non les objets mtiers
qui forment le modle.
3. Validations : Lorsque tous les composants UI ont reu leurs valeurs, JSF traverse l'arborescence de composants et demande chacun d'eux de
s'assurer que la valeur qui leur a t soumise est correcte. Si la conversion et la validation russissent pour tous les composants, le cycle de vie
passe la phase suivante. Sinon il passe la phase de Rendu de la rponse avec les messages d'erreur de validation et de conversion appropris.
4. Modification des valeurs du modle : Lorsque toutes les valeurs des composants ont t affectes et valides, les beans grs qui leur sont associs
peuvent tre mis jour.
5. Appel de l'application : Nous pouvons maintenant excuter la logique mtier. Les actions qui ont t dclenches seront excutes sur le bean gr.
La navigation entre en jeu car c'est la valeur qu'elle renvoie qui dterminera la rponse.
6. Rendu de la rponse : Le but principal de cette phase consiste renvoyer la rponse l'utilisateur. Son but secondaire est de sauvegarder l'tat de la
vue pour pouvoir la restaurer dans la phase de restauration si l'utilisateur redemande la vue.
Le thread d'excution d'un cycle requte/rponse peut passer ou non par chacune de ces tapes en fonction de la requte et de ce qui se passe au
cours de son traitement : en cas d'erreur notamment, le flux d'excution passe directement la phase de Rendu de la rponse. Quatre de ces tapes
peuvent produire des messages d'erreur : Application des valeurs de la requte (2), Validation (3), Modification des valeurs du modle (4) et Appel de
l'application (5). Avec ou sans erreur, la phase de Rendu de la rponse (6) renvoie toujours le rsultat l'utilisateur.
Petit rsum
Nous venons de le voir, crer des pages contenant des composants graphiques ne suffit pas : ces pages doivent interagir avec un back-end (un processus en arrire
plan), il faut pouvoir naviguer entre les pages et valider et convertir les donnes. JSF est une spcification trs riche : les beans grs permettent d'invoquer la couche
mtier, de naviguer dans votre application, et, grce un ensemble de classes, vous pouvez convertir les valeurs des composants ou les valider pour qu'ils
correspondent aux rgles mtiers. Grces aux annotations, le dveloppement de convertisseurs et de validateurs personnaliss est dsormais chose facile.
JSF 2.0 apporte la simplicit et la richesse aux interfaces utilisateurs dynamiques. Il reconnait nativement Ajax en fournissant une bibliothque JavaSript
permettant d'effectuer des appels asynchrones vers le serveur et de rafrachir une page par parties.
La cration d'interfaces utilisateurs, le contrle de la navigation dans les appels synchrones ou asynchrones de la logique mtier sont possibles parce que JSF
utilise le modle de conception MVC (Modle-Vue-Contrleur). Chaque partie est donc isole des autres, ce qui permet de modifier l'interface utilisateur sans
consquence sur la logique mtier et vice versa.

Le modle MVC et architecture JSF
JSF encourage la sparation des problmes en utilisant une des variantes du modle MVC. Ce dernier est un modle d'architecture permettant d'isoler la logique mtier
de l'interface utilisateur car la premire ne se mlange pas bien avec la seconde.
Avec PHP ou JSP, le mlange de la logique mtier et de l'interface utilisateur produit des applications plus difficiles maintenir et qui supportent moins bien la
monte en charge. En effet, une page JSP qui contient la fois du code Java et des instructions SQL au millieu des balises HTML : bien que ce soit
techniquement correct, imaginez la difficult de maintenir une telle page... Elle mlange deux types de dveloppement diffrents (celui du concepteur graphique
et celui de programmeur mtier) et pourrait finir par utiliser bien plus d'API encore (accs aux bases de donnes, appels d'EJB, etc.), par grer les exceptions ou
par effectuer des traitements mtiers complexes.
Avec MVC, l'application utilise un couplage faible, ce qui facilite la modification de son aspect visuel ou des rgles mtiers sous-jacentes sans pour autant
affecter l'autre composante. Par exemple, nous avons travailler sur deux vues diffrentes (conversion.xhtml), avec ou sans prise en compte d'une action Ajax,
sans que nous ayons modifier quoi que ce soit sur le bean gr. Revoici d'ailleurs les deux alternatives :
Comme le montre la figure ci-dessous, la partie modle de MVC reprsente les donnes (et leurs diffrents traitements) de l'applications ; la vue correspond
l'interface utilisateur et le contrleur gre la communication entre les deux :
1. Le modle est reprsent par le contenu, qui est quelque fois stock dans une base de donnes et affich dans la vue ; il ne se soucie pas de l'aspect
que verra l'utilisateur. Avec JSF, il peut tre form de backing beans, d'appels EJB, d'entits JPA, etc.
2. La vue JSF est la vritable page XHTML (XHTML est rserve aux interfaces web, mais il pourrait s'agir d'autre type de vue, comme WML pour les
dispositifs mobiles). Une vue fournit une reprsentation graphique d'un modle et un modle peut avoir plusieurs vues pour prvoir un affichage
sous forme de formulaire ou sous forme de liste, par exemple.
3. Lorsqu'un utilisateur manipule une vue, celle-ci informe un contrleur des modifications souhaites. Ce contrleur se charge alors de rassembler,
convertir et valider les donnes, appelle la logique mtier puis produit le contenu en XHTML. Avec JSF, le contrleur est un objet FacesServlet.
Cette servlet est dj fabrique. Nous n'avons aucun code crire en son sein. Nous pouvons toutefois influencer son comportement au
moyen d'annotations spcifiques, comme par exemple @ManagedBean. Dans ce cas l, la servlet s'occupera alors de gnrer un nouvel
objet correspondant la classe du bean gr avec une dure de vie adapte.
Architecture JSF au travers de l'exemple complet de conversion
Nous allons valider tous les diffrents concepts que nous venons de dcouvrir durant tout le dbut de cette tude au travers du projet de conversion sur lequel nous
avons galement travaill. Nous en profiterons pour dcouvrir l'architecture d'une application web trait avec JSF et de voir comment se traite la gestion des resources
ainsi que le descripteur de dploiement (web.xml).
Nous allons maintenant suivre toute la procdure pour raliser ce projet au travers de l'environnement Netbeans. Ce projet, je le rappelle, permet de raliser la
conversion montaire des uros vers les francs (uniquement dans ce sens).
Mise en place du projet
1. Cration d'un projet de type application Web :
2. Nom du projet Francs :
3. Choix du serveur d'applications et des rglages de base :
4. Prise en compte de la technologie JSF pour cette application web :
Feuille de style CSS et gestion des ressources
La plupart des composants ont besoin de ressources externes pour s'afficher correctement : <h:graphicImage> a besoin d'une image, <h:commandButton>
peut galement afficher une image pour reprsenter le bouton, <h:outputScript> rfrence un fichier JavaScript et surtout les composants peuvent galement
appliquer des styles CSS (Sujet qui m'intresse ici).
Avec JSF, une ressource est un lment statique qui peut tre transmis aux lments afin d'tre affich (images) ou trait (CSS) par le navigateur. JSF
2.0 permet d'assembler directement les ressources dans un fichier jar spar, avec un numro de version et une locale, et de les placer la racine de
l'application web, sous le rpertoire suivant :
resources/<identifiant_ressource>
ou
META-INF/resources/<identifiant_ressource>
<identifiant_ressource> est form de plusieurs sous-rpertoire indiqus sous la forme :
[locale/ ] [nomBibliothque/ ] nomRessource [ /versionRessource]
Tous les lments entre crochets sont facultatifs. La locale est le code du langage, suivi ventuellement d'un code de pays (en, en_US, pt,
pt_BR). Comme l'indique cette syntaxe, vous pouvez ajouter un numro de version la bibliothque ou la ressource elle-mme.
Voici quelques exemples :
resources/principal.css
resources/css/principal.css
Aprs toutes ces considrations techniques, nous allons maintenant laborer l'ensemble de nos styles de la page dans une feuille spare. La suite
nous montre la procdure suivre :
1. Netbeans permet de prendre en compte les feuilles de styles :
2. Le plus important et de bien choisir l'emplacement, avec bien sr le nom de votre feuille de style :
3. Voici le rsultat avec la prise en compte de l'emplacement :
principal.css
root {
display: block;
}
body {
background-color: orange;
color: maroon;
font-family: Verdana,Arial,Helvetica,sans-serif;
text-align: center;
}
.saisie, .resultat {
background-color: yellow;
text-align: right;
font-weight: bold;
color: green;
}
.resultat {
color: red;
}
.erreur {
color: black;
}
Le fait de choisir une feuille de style plutt que d'intgrer les styles directement dans la vue me parat tre une attitude de bon dveloppeur. Il faut
toujours sparer la mise en forme de votre page web par rapport son ossature, surtout si vous devez en construire plusieurs. Toutes les pages
respecterons ainsi la mme charte graphique. A tout moment, vous pouvez changer cette charte sans remettre en cause les structures de
dveloppement de vos diffrentes vues. Pour finir, lorsque vous prenez une feuille de style part entire, vous bnficiez d'un diteur CSS intgr, ce
qui n'est pas ngligeable.
Le contrleur FacesServlet et le descripteur de dploiement web.xml
Lorsqu'un utilisateur manipule une vue, celle-ci informe un contrleur des modifications souhaites. Ce contrleur se charge alors de rassembler, convertir et
valider les donnes, appelle la logique mtier puis produit le contenu en XHTML. Avec JSF, le contrleur est un objet FacesServlet.
FacesServlet est une implmentation de javax.servlet.Servlet qui sert de contrleur central par lequel passent toutes les requtes. Comme le montre la
figure ci-dessous, la survenue d'un vnement, lorsque l'utilisateur clique sur un bouton, par exemple, provoque l'envoi d'une notification au serveur
via HTTP ; celle-ci est intercepte par javax.faces.webapp.FacesServlet, qui examine la requte et excute diffrentes actions sur le modle l'aide des
beans grs.
En coulissse, la FacesServlet prend les requtes entrantes et donne le contrle l'objet javax.faces.lifecycle.LifeCycle. A l'aide d'une mthode de
fabrique, elle cre un objet javax.faces.contextFacesContext qui contient et traite les informations d'tat de chaque requte. L'objet Lifecycle utilise ce
FacesContext en six tapes (dcrites au chapitre prcdent) avant de produire la rponse.
Les requtes qui doivent tre traites par la FacesServlet sont rediriges l'aide d'une association de servlet dans le descripteur de dploiement
(web.xml) qui se situe dans le rpertoire WEB-INF. Les pages web, les beans grs, les convertisseurs, etc. doivent tre assembls l'aide de ce fichier.
1. Ce fichier dfinit la javax.faces.webapp.FacesServlet en lui donnant un nom (Faces Servlet, ici) et une association. Dans cet exemple, toutes les
requtes dont le prfixe est faces/ sont associes pour tre gres par la servlet - toute requte de la forme http://localhost:8080/Francs/faces/*.xhtml
sera donc trait par JSF.
2. Nous pouvons en profiter pour dfinir la page d'accueil l'aide du marqueur <welcome-file>, ici conversion.xhtml. Cette balise est optionnelle. Si
vous ne voulez pas la dfinir, la page d'accueil doit alors s'appeler index.xhtml.
3. En option, vous pouvez galement configurer quelques paramtres spcifiques JSF dans l'lment <context-param>. dont la liste est propose ci-
dessous :
Paramtre Description
javax.faces.CONFIG_FILES Dfinit une liste de chemins de ressources lies au contexte dans lequel JSF
recherchera les ressources.
javax.faces.DEFAULT_SUFFIX Permet de ffinir une liste de suffixes possibles pour les pages ayant du contenu JSF
(.xhtml, par exemple).
javax.faces.LIFECYCLE_ID Identifie l'instance LifeCycle utilise pour traiter les requtes JSF.
javax.faces.STATE_SAVING_METHOD Dfinit l'emplacement de sauvegarde de l'tat. Les valeurs possibles sont server
(valeur par dfaut qui indique que l'tat sera gnralement sauvegard dans un objet
HttpSession) et client (l'tat sera sauvegard dans champ cach lors du prochain
envoi de formulaire).
javax.faces.PROJECT_STAGE Dcrit l'tape dans laquelle se trouve cette application JSF dans le cycle de vie
(Development, UnitTest, SystemTest ou Production). Cette information peut tre
utilise par une implmentation de JSF pour amliorer les performances lors de la
phase de production en utilisant un cache pour les ressources, par exemple.
javax.faces.DISABLE_FACELET_JSF_VIEWHANDLER Dsactive Facelets comme langage de dclaration de page (PDL).
javax.faces.LIBRARIES Liste des chemins qui seront considrs comme une bibliothque de marqueurs
Facelets.
Le bean gr Conversion
Comme nous l'avons voqu plus haut dans ce chapitre, le modle MVC encourage la sparation entre le modle, la vue et le contrleur. Avec Java EE, les
pages JSF forment la vue et la FacesServlet est le contrleur. Les beans grs, quant eux, sont une passerelle vers le modle.
1. Les beans grs sont des classes Java annotes. Ils constituent le coeur des applications web car ils excutent la logique mtier (ou la dlguent aux
EJB, par exemple), grent la navigation entre les pages et stockent les donnes. Une application JSF typique contient un ou plusieurs beans grs
qui peuvent tre partags par plusieurs pages.
2. Les donnes sont stockes dans les attributs du bean gr, qui, en ce cas, est galement appel "backing bean". Un backing bean dfinit les
donnes auxquelles est li un composant de l'interface utilisateur (la cible d'un formulaire, par exemple). Pour tablir cette liaison, nous utilisons
EL, le langage d'expressions.
3. Ecrire un bean gr est aussi simple qu'crire un EJB ou une entit JPA puisqu'il s'agit simplement de crer une classe Java annote par
@ManagedBean (ou @Named, nous verrons la diffrence entre les deux critures lors du prochain chapitre).
4. Les beans grs sont des classes Java prises en charge par la FacesServlet. Les composants de l'interface utilisateur sont lis aux proprits du bean
(backing bean) et peuvent invoquer des mthodes d'action.
5. Bien qu'un bean gr puisse tre une simple classe annote, sa configuration peut tre personnalise grce aux lments de @ManagedBean et
@ManagedProperty (voir pour plus de dtail dans le chapitre suivant).
6. La prsence de l'annotation @javax.faces.model.ManagedBean sur une classe l'enregistre automatiquement comme un bean gr. C'est la
FacesServlet qui gre cette classe. Par dfaut, le nom du bean gr (objet) est celui de la classe commenant par une minuscule. Il est possible de
choisir un autre nom en spcifiant l'attribut name de l'annotation @ManagedBean.
7. Les composants de l'interface utilisateur tant lis aux proprits du bean gr, changer son nom par dfaut a des rpercussions sur la faon
d'appeler une proprit ou une mthode.
8. Les objets crs dans le cadre d'un bean gr ont une certaine dure de vie et peuvent ou non tre accessibles aux composants de l'interface
utilisateur ou aux objets de l'application. Cette dure de vie et cette accessibilt sont regroupes dans la notion de porte. Plusieurs annotations (que
nous tudierons plus en dtail dans la chapitre suivant) permettent de dfinir la porte d'un bean gr.
9. La porte que je choisi pour le bean gr est @ViewScoped. Cet objet est alors disponible dans une vue donne jusqu' sa modification. Son tat
persiste jusqu' ce que l'utilisateur navigue vers une autre vue, auquel cas il est supprim.
Aprs toutes ces rflexions, je vous propose maintenant de crer notre bean gr Conversion l'aide de notre outil de dveloppement Netbeans. Voici
la procdure suivre :
1. Cration d'un nouveau bean gr :
2. Demande de cration d'un bean gr dont le nom de l'objet sera conv issu de la classe Conversion et dont la dure de vie correspond exactement
la dure de vie de la page afficher :
3. Nous plaons toute la logique mtier dans ce bean gr, et c'est lui qui ralise la conversion ncessaire. Voir le code ci-dessous.
bean.Conversion.java
package bean;
import javax.faces.bean.*;
@ManagedBean(name="conv")
@ViewScoped
public class Conversion {
private final double TAUX = 6.55957;
private double euro;
private double franc;
public double getEuro() { return euro; }
public void setEuro(double euro) { this.euro = euro; }
public double getFranc() { return franc; }
public void setFranc(double franc) { this.franc = euro * TAUX; }

public void euroFranc() { franc = euro * TAUX; }
}
1. Mise part les annotations, nous retrouvons une classe normale avec des proprits et une mthode de traitement.
2. Ces proprits sont indispensables pour que la page web puisse y accder et qu'il y ait une interaction possible entre le modle et la vue.
3. L'annotation @ManagedBean est galement indispensable pour stipuler que cette classe doit tre prise en compte par le contrleur (tre gre). C'est
finalement l'quivalent d'un dispositif de configuration puisque nous demandons ainsi que le nom de l'objet correspondant s'appelle conv. Par
ailleurs, nous configurons galement la dure de vie de cet objet pour qu'il soit en adquation avec la vue au moyen de l'annotation @ViewScoped.
4. Grce ces simples annotations, il est trs facile de changer de nom d'objet ainsi que sa dure de vie.
La vue conversion.xhtml
Le modle, vous venez de le dcouvrir est trs simple. Nous nous intressons maintenant notre dernier lment de l'application wen, savoir la vue, plus
prcisment la page conversion.xhtml.
Lorsque vous travaillez avec la vue, vous disposez d'un certain nombre de composants (marqueurs) dj construits qui sont installs dans des
bibliothques spcifiques qu'il faut prendre en compte lors de l'laboration de vos pages web si vous dsirez les utiliser. Voici le tableau qui recense
les bibliothques prfabriques :
URI
Prfixe
classique
Description
http://java.sun.com/jsf/html h Contient les composants et leurs rendus HTML (h:commandButton, h:inputText, etc.)
http://java.sun.com/jsf/core f Contient les actions personnalises indpendantes d'un rendu particulier (f:convertNumber,
f:validateDoubleRange, f:param, etc.)
http://java.sun.com/jsf/facelets ui Marqueurs pour le support les modles de page.
http://java.sun.com/jsf/composite composite Sert dclarer et dfinir des nouveaux composants personnaliss.
http://java.sun.com/jsp/jstl/core c Les pages Facelets peuvent ventuellement utiliser certains marqueurs issus de JSP (c:if, c:forEach et
c:catch). A viter si possible.
http://java.sun.com/jsp/jstl/functions fn Les pages Facelets peuvent utiliser tous les marqueurs de fonctions issus de la technologie JSP.
conversion.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title><h:outputText value="Conversion entre les uros et les francs" /></title>
</h:head>

<h:outputStylesheet library="css" name="principal.css" />

<h:body>
<h3><h:outputText value="Conversion entre les uros et les francs" /></h3>
<hr />
<h:form>
<h:inputText value="#{conv.euro}"
styleClass="saisie"
id="euro"
converterMessage="Il faut une valeur montaire"
validatorMessage="Uniquement les nombres positifs"
required="true"
requiredMessage="Prcisez votre valeur montaire">

<f:convertNumber type="currency" currencySymbol=""/>
<f:validateDoubleRange minimum="0.0" />
</h:inputText>

<h:commandButton value="Conversion" action="#{conv.euroFranc}" />

<h:inputText value="#{conv.franc}" readonly="true" styleClass="resultat">
<f:convertNumber type="currency" currencySymbol="F"/>
</h:inputText>

<p><h:message for="euro" styleClass="erreur"/></p>
</h:form>
</h:body>
</html>
1. Au dbut, dans la balise <html>, vous spcifiez les bibliothques qui vous serons utiles pour la constitution de votre page.
2. Par exemple, sauf cas trs rare, nous avons toujours besoin des marqueurs relatifs au rendu, comme les zones de saisie, les boutons etc. Aussi, nous
proposons l'espace de nom h (pour HTML) associ la bibliothque xmlns:h="http://java.sun.com/jsf/html".
3. Pour les marqueurs qui ralise du traitement en coulisse, comme les convertisseurs et les validateurs, nous introduisons la bibliothque
xmlns:f="http://java.sun.com/jsf/core". (Nous aurions pu prendre l'espace de nom c, mais il est gnralement dj utilis par la JSTL). Quelquefois,
je prend comme espace de nom core.
4. La balise <h:outputStylesheet library="css" name="principal.css" /> nous permet de prendre en compte la feuille de style principal.css que nous
avons mise en oeuvre au pralable, dans la bibliothque (rpertoire) css. Vous pouvez placer votre feuille de style directement dans le rpertoire
resources (donc sans bibliothque), auquel cas vous n'avez plus spcifier l'attribut library.
5. Nous retrouvons pratiquement le mme code que nous avons dj consult mainte fois. Vous remarquez toutefois la prsence d'un nouveau
marqueur <h:message for="euro" styleClass="erreur"/> qui permet d'avertir l'utilisateur d'une mauvaise utilisation sur la zone de saisie des uros.
6. Cette balise doit toujours tre rattache une autre au moyen de l'attribut for. De la mme faon, la balise en question, comme ici <h:inputText
value="#{conv.euro}" id="euro">, doit possder l'attribut id l'intrieur duquel vous spcifiez un nom de variable prendre en compte.
7. Toujours dans cette balise, vous avez la possibilit de spcifier les messages qui s'afficheront automatiquement lors d'une erreur de saisie
particulire. Ici, nous proposons des messages d'erreur de conversion, de validation et de champ non vide, respectivement avec les atttributs
converterMessage, validatorMessage et requiredMessage.
8. Voici d'ailleurs les diffrents rsultats obtenus suivant les cas d'utilisation :
N'oubliez pas que nous ici dans la technique des pages web dynamiques, c'est--dire que tout les marqueurs que nous proposons ne sont pas envoys
au client. La page web conversion.xhtml reste sur le serveur et le systme JSF envoie une page web au format HTML classique suivant la requte
propose par le client (pas besoin d'une installation Java spcifique). Voici justement le code source de la page web qui est envoye par rapport aux
valeurs proposes ci-dessus :
Conclusion

Les beans grs et la navigation
Comme nous l'avons voqu plus haut dans ce chapitre, le modle MVC encourage la sparation entre le modle, la vue et le contrleur. Avec Java EE, les pages JSF
forment la vue et la FacesServlet est le contrleur. Les beans grs, quant eux, sont une passerelle vers le modle. Je rappelle les points importants que nous avons
dj voqu dans le chapitre prcdent :
1. Les beans grs sont des classes Java annotes. Ils constituent le coeur des applications web car ils excutent la logique mtier (ou la dlguent aux EJB, par
exemple), grent la navigation entre les pages et stockent les donnes. Une application JSF typique contient un ou plusieurs beans grs qui peuvent tre
partags par plusieurs pages.
2. Les donnes sont stockes dans les attributs du bean gr, qui, en ce cas, est galement appel "backing bean". Un backing bean dfinit les donnes
auxquelles est li un composant de l'interface utilisateur (la cible d'un formulaire, par exemple). Pour tablir cette liaison, nous utilisons EL, le langage
d'expressions.
3. Ecrire un bean gr est aussi simple qu'crire un EJB ou une entit JPA puisqu'il s'agit simplement de crer une classe Java annote par @ManagedBean ou
@Named.
4. Les beans grs sont des classes Java prises en charge par la FacesServlet. Les composants de l'interface utilisateur sont lis aux proprits du bean (backing
bean) et peuvent invoquer des mthodes d'action.
5. Bien qu'un bean gr puisse tre une simple classe annote, sa configuration peut tre personnalise grce aux lments de @ManagedBean et
@ManagedProperty.
6. La prsence de l'annotation @javax.faces.model.ManagedBean ou @javax.inject.Named sur une classe l'enregistre automatiquement comme un bean gr.
C'est la FacesServlet qui gre cette classe. Par dfaut, le nom du bean gr (objet) est celui de la classe commenant par une minuscule. Il est possible de
choisir un autre nom en spcifiant l'attribut name de l'annotation @ManagedBean ou de l'annotation @Named.
7. Les composants de l'interface utilisateur tant lis aux proprits du bean gr, changer son nom par dfaut a des rpercussions sur la faon d'appeler une
proprit ou une mthode.
Pour conclure sur cette premire approche, un bean gr doit respecter les contraintes suivantes :
1. Le classe doit tre annote par @ManagedBean ou @Named.
2. La classe doit avoir une porte (qui vaut par dfaut @RequestScoped). (Nous dcouvrirons les diffrentes portes dans la suite du chapitre).
3. La classe doit tre publique et non finale ni abstraite.
4. La classe doit fournir un constructeur public sans paramtre qui sera utilis par le conteneur pour crer les instances.
5. La classe ne doit pas dfinir de mthode finalize().
6. Pour tre lis un composant graphique de la vue, les attributs doivent avoir des getters et des setters public (ce que nous appelons des proprits). En ralit,
le point de contact d'un composant graphique avec la proprit se fait toujours au travers des mthodes. Du coup, dans certains cas, il n'est pas toujours
ncessaire d'avoir un attribut qui conserve la valeur. Par contre, la syntaxe du getter et du setter doit tre respecte.
Les beans CDI
Jusqu' prsent, nous avons surtout travaill sur les beans manags au travers de l'annotation @ManagedBean. Cependant, les beans manags sont assez limits. JSF,
avec sa dernire version, dfinie un modle de bean gr plus flexible, nomm CDI (Contexts and Dependency Injection). Ce bean, comme son nom l'indique, est li
un context (comme, par exemple, la requte en cours, la session actuelle du navigateur, ou mme le cycle de vie du context de l'utilisateur.
CDI spcifie un mcanisme pour injecter des beans grs, pour intercepter les mthodes d'appel, et prendre en compte la vole les vnements lies aux
diffrentes requtes du client web.
Ceci dit, nous pouvons continuer prendre des beans manags. Dans bien des cas ils sont gnralement suffisants, notamment si nous n'avons pas besoin
d'interaction. Ils permettent d'avoir une gestion autonome du modle.
L o les beans CDI sont importants, c'est justement lorsque nous dsirons avoir une forte interaction avec les autres lments du serveur d'applications, comme
les beans sessions, les entits, les applications web de type Rest. Ainsi, par exemple, l'injection permet d'avoir un bean session qui sert galement de bean gr
en relation directe avec la vue, condition toutefois que ce bean session soit de type stateful afin de permettre le suivi des diffrentes requtes de l'application
web.
Aprs toutes ces dfinissions, venons en maintenant l'criture proprement dite. Nous retrouvons pratiquement la mme syntaxe que les beans manags. Vous
avez juste utiliser l'annotation @Named en lieu et place de l'annotation @ManagedBean, comme ci-dessous :
bean.Conversion.java
package bean;
import javax.io.Serializable;
import javax.inject.Named; // importation diffrente
import javax.enterprise.context.SessionScoped; // importation diffrente
@Named("conv")
@SessionScoped // la dure de vie Vue n'existe pas dans les beans CDI
public class Conversion implementation Serializable { // Nous devons galement faire en sorte que l'objet soit srialis
private final double TAUX = 6.55957;
private double euro;
private double franc;
public double getEuro() { return euro; }
public void setEuro(double euro) { this.euro = euro; }
public double getFranc() { return franc; }
public void setFranc(double franc) { this.franc = euro * TAUX; }

public void euroFranc() { franc = euro * TAUX; }
}
1. Mise part quelques petits dtails, le code du bean gr correspondant la conversion demeure similaire.
2. Notamment nous pouvons conserver la mme vue que prcdemment. Ainsi, l'accs une proprit de ce bean se fait exactement de la mme faon
: #{conv.euro}, par exemple.
3. Les diffrences notables concerne les importations d'une part, et surtout, notre bean doit tre srialis.
4. Il existe des dures de vie diffrentes dans les deux types de bean.
5. La mise en oeuvre des beans CDI est galement diffrente avec Netbeans. Nous verrons comment procder lors du prochain exemple.
Porte et dure de vie des beans grs
Les objets crs dans le cadre d'un bean gr ont une certaine dure de vie et peuvent ou non tre accessibles aux composants de l'interface utilisateur ou aux objets
de l'application. Cette dure de vie et cette accessibilt sont regroupes dans la notion de porte. Plusieurs annotations permettent de dfinir la porte d'un bean gr.
Lorsque vous dfinissez un bean gr, vous tes obligs de spcifier galement sa porte. Trois portes sont communes au beans manags et beans CDI : les
portes de type Session, de type Requte et de type Application.
JSF 2.0 rajoute les portes de type Vue et de type Personnalise qui ne sont pas supportes par les beans CDI mais qui proposent en contre partie une porte
plus puissante qui s'appelle Conversation.
Avec JSF 2.0, vous pouvez utiliser les annotations suivantes pour prendre en compte les portes communes : @SessionScoped, @RequestScoped et
@ApplicationScoped. Notez que ces annotations sont dcrites dans le paquetage javax.faces.bean pour les beans manags et dans le paquetage
javax.enterprise.context pour les beans CDI.
Dfinition de chacune des portes
1. @ApplicationScoped : Il s'agit de l'annotation la moins restrictive, avec la plus longue dure de vie. Les objets crs sont disponibles dans tous les cycles
requte/rponse de tous les clients utilisant l'application tant que celle-ci est active. Ces objets peuvent tre appels de faon concurrente et doivent dont tre
thread-safe (c'est--dire utiliser le mot-cl synchronized). Les objets ayant cette porte peuvent utiliser d'autres objets sans porte ou avec une porte
d'application.
Ce type de bean est construit ds l'apparition de la premire requte d'un client et reste actif jusqu' ce que l'application web soit enleve du serveur
d'applications. Cependant, il est possible de faire en sorte que ce bean soit actif plus tt, bien avant que la premire page soit affiche, ds que
l'application web est dploye sur le serveur, au moyen de l'attribut eager, comme suit :
@ManagedBean(eager=true)
2. @SessionScoped : Ces objets sont disponibles pour tous les cycles requte/rponse de la session du client. Leur tat persiste entre les requtes et dure jusqu'
la fin de la session. Ils peuvent utiliser d'autres objets sans porte, avec une porte de session ou d'application.
Rappelez-vous que le protocole HTTP est sans tat. Le navigateur envoie une requte au serveur, le serveur renvoie la rponse, et ni le navigateur ni
le serveur sont dans l'obligation, dans ce protocole, de garder en mmoire la transaction.
3. @ViewScoped : (Uniquement pour les beans manags) : Ces objets sont disponibles dans une vue donne jusqu' sa modification. Leur tat persiste jusqu' ce
que l'utilisateur navigue vers une autre vue, auquel cas il est supprim. Ils peuvent utiliser d'autres objets sans porte, avec une porte de vue, de session ou
d'application.
4. @RequestScoped : Il s'agit de la porte par dfaut. Ces objets sont disponibles du dbut d'une requte jusqu'au moment o la rponse est envoye au client.
Un client pouvant excuter plusieurs requtes tout en restant sur la mme vue, la dure @ViewScoped est suprieure celle de @RequestScoped. Les objets
ayant cette porte peuvent utiliser d'autres objets sans porte, avec une porte de requte, de vue, de session ou d'application.
Avec cette porte, la dure de vie est trs courte. La cration du bean se ralise ds qu'une requte est propose et se dtruit rapidement ds que la
rponse t renvoye au client. Cela veut dire qu'une nouvelle instance est cre chaque requte du client. Du coup, pour une mme vue,
beaucoup de mmoires risquent d'tre utilises pour rien.
5. @NoneScoped : Les beans grs ayant cette porte ne sont visibles dans aucune page JSF; ils dfinissent des objets utiliss par d'autres beans grs de
l'application. Ils peuvent utiliser d'autres objets avec la mme porte.
6. @ConversationScoped : (Uniquement pour les beans CDI) : Cette porte est intressante lorsque vous avez besoin de grer plusieurs onglets pour une mme
session. C'est un petit peu l'intermdiaire entre la porte de type requte et la porte de type session.
La porte des beans grs doit tre judicieusement choisie : vous ne devez leur donner que la porte dont ils ont besoin. Des beans ayant une porte trop grande
(@ApplicationScoped, par exemple) augmentent l'utilisation mmoire et l'utilisation du disque pour leur persistance ventuelle. Il n'y a aucune raison de donner
une porte d'application un objet qui n'est utilis que dans un seul composant. Inversement, un objet ayant une porte trop restreinte (@RequestScoped, par
exemple) ne sera pas disponible dans certaines parties de l'application, et ventuellement beaucoup d'objets (avec donc beaucoup de mmoires) risquent d'tre
crs pour rien.
Injection de valeurs dans les beans (@ManagedProperty et @Inject)
Dans un bean gr, vous pouvez demander au systme d'injecter une valeur dans une proprit (un attribut avec un getter et un setter) en utilisant l'annotation
@javax.faces.model.ManagedProperty (pour les beans manags) ou @javax.inject.Inject (pour les beans CDI), dont l'attribut value peut recevoir une chane ou une
expression EL.
Annotation du cycle de vie et des mthodes de rappel
L'introduction nous a montr le cycle de vie d'une page (qui compte six phases, de la rception de la requte la production de la rponse), mais le cycle de vie des
beans grs est totalement diffrent : en fait il est totalement identique celui des beans sessions sans tat.
Les beans grs qui s'excutent dans un conteneur de servlet peuvent utiliser les annotations @PostConstruct et @PreDestroy.
Ainsi, aprs avoir cr une instance de bean gr, le conteneur appelle la mthode de rappel @PostConstruct s'il y en a une. Puis le bean est li une
porte et rpond toutes les requtes de tous les utilisateurs. Toutefois, avant de supprimer le bean, le conteneur appelle la mthode @PreDestroy. Ces
mthodes permettent ainsi d'initialiser les attributs ou de crer et librer les ressources externes.
bean.GestionLivre.java
@ManagedBean ou @Named
public class GestionLivre {
...
@PostConstruct
public void dbut() { ... }
...
@PreDestroy
public void fin() { ... }
}
Langage d'expressions EL
Les instructions EL fournissent une syntaxe simple d'utilisation afin de se connecter une proprit ou proposer une action spcifique sur un bean gr. Elles
permettent facilement d'afficher les valeurs des variables ou d'accder aux attributs des objets, aux travers de leurs proprits, et disposent galement d'un grand
nombre d'oprateurs mathmatiques, logiques et relationnels.
La syntaxe de base d'une instruction EL est de la forme :
#{expression}
Les expressions EL peuvent utiliser la plupart des oprateurs Java habituels :
1. Arithmtiques : + - * / (division) % (modulo)
2. Relationnels : == (galit) != (ingalit) < (infrieur) > (suprieur) <= (infrieur ou gal) >= (suprieur ou gal)
3. Logiques : && (et) || (ou) ! (non)
4. Autre : empty (vide) () (parenthses) [ ] (crochets) . (sparateur) ?: (if arithmtique)
L'oprateur empty teste si un objet est null ou si les collections (tableaux, List, Map, etc. ) sont vides. Nous pouvons ainsi contrler, par exemple, qu'un
livre est dfini ou pas :
#{empty livre}
L'oprateur point permet d'accder un attribut d'un objet. Une autre syntaxe possible consiste utiliser l'oprateur [ ]. Nous pouvons ainsi accder
l'attribut titre de l'objet livre de la faon suivante :
#{livre.titre} ou #{livre[titre]}
Appel de mthodes
Il est galement possible d'appeler des mthodes. Si vous dsirez par exemple acheter un livre en appelant la mthode acheter() de l'objet livre :
#{livre.acheter}
Depuis la toute dernire version de JSF, nous pouvons galement proposer des paramtres aux appels de mthode :
<h:commandButton value="Suivant" action="#{unBean.naviguer(1)}" />
<h:commandButton value="Prcdent" action="#{unBean.naviguer(-1)}" />
A condition que cette mthode soit effectivement dclare avec le bon paramtre :
@ManagedBean
public class UnBean {
...
public void naviguer(int sens) { ... }
}
Actions fondamentales
Les actions fondamentales, numres dans le tableau ci-dessous, fournissent des marqueurs pour manipuler les beans grs, des variables, traiter des erreurs, effectuer
des tests et excuter des boucles et des itrations :
Action Description
<c:remove> Supprime une variable.
<c:catch> Capture une exception java.lang.Throuwable lance par l'une de ses actions imbriques.
<c:if> Teste si une expression est vrai (la plupart du temps, il est prfrable d'utiliser plutt l'attribut rendered prsent dans toutes les balises de JSF).
<c:choose> Fournit plusieurs alternatives exclusives.
<c:when> Reprsente une alternative dans une section <c:choose>.
<c:otherwise> Reprsente la dernire alternative d'une action <c:choose>.
<c:forEach> Rpte son corps pour chaque lment d'une collection ou un nombre fix de fois.
Objets prdfinies
Il existe des identificateurs spciaux, que nous pouvons atteindre directement dans les diffrentes vues, qui correspondent des objets spcifiques dj prdfinis. Ce
sont des objets implicites parce qu'une page peut les utiliser sans avoir besoin de les dclarer ou de les initialiser explicitement. Ces objets (numrs dans le tableau
ci-dessous) sont utilisable l'aide des expressions EL.
Objet implicite Description Type renvoy
application Reprsente l'environnement de l'application web. Sert obtenir les paramtres de configuration de cette application. Object
applicationScope Associe les noms des attributs de l'application leurs valeurs. Map
component Dsigne le composant courant. UIComponent
cc Dsigne le composant composite courant. UIComponent
cookie Dsigne un Map contenant les noms des cookies (cls) et des objets Cookie. Map
facesContext Dsigne l'instance FacesContext de cette requte. FacesContext
header Fait correspondre chaque nom d'en-tte HTTP une seule valeur de type String. Map
headerValue Fait correspondre chaque nom d'en-tte HTTP un tableau String[] contenant toutes les valeurs de cet en-tte. Map
initParam Fait correspondre les noms des paramtres d'initialisation du contexte leurs valeurs de type String. Map
param Fait correspondre chaque nom de paramtre une seule valeur de type String. Map
paramValues Fait correspondre chaque nom de paramtre un tableau String[] contenant toutes les valeurs de ce paramtre. Map
request Reprsente l'objet requte HTTP. Object
requestScope Fait correspondre les noms des attributs de la requte leurs valeurs. Map
resource Indique l'objet ressource. Object
session Reprsente l'objet session HTTP. Object
session Reprsente l'objet session HTTP. Object
sessionScope Fait correspondre les noms des attributs de la session leurs valeurs. Map
view Reprsente la vue courante. UIViewRoot
viewScope Fait correspondre les noms des attributs de la vue leurs valeurs. Map
Tous ces objets implicites sont de vrais objets avec des interfaces. Vous pouvez accder leurs attributs avec EL :
1. Ainsi, #{view.locale}, par exemple, permet d'obtenir le pays dans lequel est consult cette page (en_US, fr_FR, etc.).
2. Si vous stockez un livre dans la porte de la session, par exemple, vous pouvez l'atteindre avec #{sessionScope.livre}.
3. Vous pouvez mme utiliser un alogorithme plus labor pour afficher tous les en-ttes HTTP et leurs valeurs :
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core">

<h:body style="background-color: yellow; font-weight: bold">
<h3>
<h:outputText value="Lecture des en-ttes de la requte HTTP" />
<h:outputText value=" (En france)" rendered="#{view.locale == 'fr_FR'}" />
</h3>
<hr />
<c:forEach items="#{headerValues}" var="lment">
<h:outputText value="#{lment.key}" style="color: mediumslateblue" /> =
<c:forEach var="valeur" items="#{lment.value}">
<h:outputText value="#{valeur}" escape="false" style="color: brown" />
<br />
</c:forEach>
</c:forEach>
</h:body>
</html>
Navigation
Les applications web sont formes de plusieurs pages entre lesquelles vous devez naviguer. Selon le cas, il peut exister diffrents niveaux de navigation avec des flux
de pages plus ou moins labors.
JSF dispose de plusieurs options de navigation et vous permet de contrler le flux page par page ou pour toute l'application.
Navigation statique
Les composants <h:commandButton> et <h:commandLink> permettent de passer simplement d'une page une autre en cliquant sur un bouton ou sur un
lien sans effectuer aucun traitement intrinsque. Il suffit d'initialiser leur attribut action avec le nom de la page vers laquelle vous voulez vous rendre. Ici, par
exemple, nous sommes dans la page de configuration du jeu qui se nomme justement "configurer.xhtml". Voici le bouton de navigation que nous pourrions
avoir dans cette page pour demander passer la page "alea.xhtml" correspondant au jeu lui-mme :
<h:commandButton value="Commencer le jeu" action="alea.xhtml" />
Navigation dynamique
Cependant, la plupart du temps, ceci ne suffira pas car vous aurez besoin d'accder une couche mtier ou une base de donnes pour rcuprer ou traiter
des donnes. En ce cas, vous aurez besoin d'un bean gr. Par exemple, avant de commencer jouer, nous avons besoin de faire un certain nombre de
traitement avant que le jeu soit totalement prt. Dans cette situation, le flux des pages reste simple, mais ces deux pages ont pourtant besoin d'un bean gr
(Nombre) pour traiter la fois la logique mtier ainsi que la navigation. Elles utilisent toujours les composants bouton (ou lien) pour naviguer et interagir
avec ce bean.
Il suffit juste de prciser la mthode du bean gr qui va traiter la logique mtier (prparer le jeu) et s'occuper ensuite de la navigation. Ici, par
exemple, c'est la mthode recommencer() du bean nombre qui est appele :
<h:commandButton value="Commencer le jeu" action="#{nombre.recommencer}" />
Les composants bouton et lien n'appellent pas directement la page vers laquelle ils doivent se rendre : ils appellent des mthodes du bean gr qui
prennent en charge cette navigation et laissent le code dcider de la page qui sera charge ensuite. La navigation utilise un ensemble de rgles qui
dfinissent tous les chemins de navigation possibles de l'application. Dans la forme la plus simple de ces rgles de navigation, chaque mthode du
bean gr dfinit directement la page vers laquelle elle doit aller.
@Named
@SessionScoped
public class Nombre implements Serializable {
...
public String recommencer() {
alea = (int)(Math.random()*valeurMax)+1;
tentative = 0;
valeur = 0;
test = false;
return "alea.xhtml";
}
}
Ainsi, quand le <h:commandButton> invoque la mthode recommencer(), celle-ci initialise le jeu, tire le nombre alatoire et renvoie le nom de la page
vers laquelle naviguer ensuite : alea.xhtml. La FacesServlet redirigera alors le flux de page vers la page dsire. Remarquez au passage, le type de
retour String de cette mthode recommencer().
La chane renvoye peut prendre plusieurs formes. Ici, nous avons utilis la plus simple : le nom de la page. L'extension de fichier par dfaut tant
.xhtml, nous aurions mme pu simplifi le code en supprimant l'extension.
@Named
@SessionScoped
public class Nombre implements Serializable {
...
public String recommencer() {
alea = (int)(Math.random()*valeurMax)+1;
tentative = 0;
valeur = 0;
test = false;
return "alea";
}
}
Les exemples prcdentes nous ont montr une navigation simple o une page n'avait qu'une seule rgle de navigation et une seule destination. Ce
n'est pas un cas si frquent : les utilisateurs peuvent gnralement tre redirigs vers des pages diffrents en fonction de certaines conditions.
Cette navigation, l encore, peut tre mise en place dans les beans grs. Le code suivant utilise une instruction switch pour rediriger l'utilisateur vers
trois pages possibles. Si nous renvoyons la valeur null, l'utilisateur reviendra sur la page sur laquelle il se trouve dj.
public String uneMthode() {
switch (valeur) {
case 1 : return "page1.xhtml"; break;
case 2 : return "page2.xhtml"; break;
case 3 : return "page3.xhtml"; break;
default : return null; break;
}
}
Redirection et mthodes POST et GET du protocole HTTP
Vous pouvez solliciter l'implmentation JSF pour vous rediriger vers une autre vue. JSF envoie alors une redirection HTTP au client. La redirection est envoye
au navigateur client avec l'URL correspondant la nouvelle page. Le navigateur client soumet alors cette nouvelle requte en utilisant la mthode GET du
protocole HTTP.
La redirection est moins rapide que la navigation classique puisque vous proposer une requte supplmentaire au navigateur. Cependant, la
redirection assure au navigateur de mettre jour systmatiquement la page web visualiser.
1. La redirection est directive. Elle supplante les rgles de navigations classiques. Pour la mettre en oeuvre, il suffit de rajouter la chane suivante :
?faces-redirect=true
2. Voici ce que nous pouvons proposer sur un composant <h:commandButton> :
<h:commandButton value="Accueil" action="accueil?faces-redirect=true" />
3. Par nature, les composants <h:commandButton> propose des requtes HTTP de type POST. Si vous dsirez plutt proposer des requtes de type
GET, prenez alors le composant <h:button> comme suit :
<h:button value="Accueil" outcome="accueil" />
Vous remarquez la prsence de l'attribut outcome de ce composant <h:button> en lieu et place de l'attibut action du composant
<h:commandButton>. Il existe une diffrence fondamentale de comportement. Avec outcome, vous pouvez vous rattacher une proprit
d'un bean gr, mais surtout pas l'appel d'une mthode. Pour action, vu d'ailleurs son nom, c'est l'inverse, c'est--dire que normalement
cet attribut est utilis pour faire appel la mthode qui gre la navigation.
4. Dans les requtes GET, nous avons quelquefois besoin de rajouter des paramtres qui vont servir exploiter correctement la demande. Le plus
facile, mon avis, est de rajouter une balise <f:param> pour chaque paramtre que vous souhaitez prendre en compte dans votre soumissions :
<h:button value="Accueil" includeViewParams="true" outcome="accueil">
<f:param name="utilisateur" value="#{bean.personne}">
<f:param name="administrateur" value="non">
</h:button>
Application web qui propose un jeu de tirage alatoire d'un nombre
Pour terminer ce chapitre, je vous propose de prendre en compte ces notions de navigation avec pour modle un bean CDI au travers d'un projet spcifique. Je vous
propose de faire un petit jeu qui nous permet de retrouver un nombre dtermin alatoirement avec un nombre de coup et une valeur maximale limites.
Nous allons maintenant suivre toute la procdure pour raliser ce projet au travers de l'environnement Netbeans.
Mise en place du projet
1. Cration d'un projet de type application Web :
2. Nom du projet Alea :
3. Choix du serveur d'applications et des rglages de base :
4. Prise en compte de la technologie JSF pour cette application web :
Descripteur de dploiement web.xml
L'application web comporte cette fois-ci deux vues, la premire (configurer.xhtml) permet de configurer le jeu en spcifiant la valeur limite du nombre
rechercher avec galement un nombre de coup limite, la deuxime (alea.xhtml) concerne le jeu lui-mme. J'aimerai que la premire page soit affiche ds que
nous sollicitons cette application web. Voici ce que nous pouvons proposer au niveau du descripteur de dploiement :
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/configurer.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Le bean gr Nombre
Une fois que le projet est en place, la premire dmarche avant de s'intresser aux vues, est de s'occuper du modle qui va raliser tous les traitements
ncessaires en coulisse. Pour changer, par rapport au premier projet de conversion, le modle sera mis en oeuvre au travers d'un bean CDI.
bean.Nombre.java
package bean;
import javax.inject.*;
import javax.enterprise.context.*;
import java.io.Serializable;
@Named
@SessionScoped
public class Nombre implements Serializable {
private int valeurMax = 20;
private int tentativeMax = 4;
private int valeur;
private int alea;
private int tentative;
private boolean test;
public int getTentativeMax() { return tentativeMax; }
public void setTentativeMax(int tentativeMax) { this.tentativeMax = tentativeMax; }
public int getValeurMax() { return valeurMax; }
public void setValeurMax(int valeurMax) { this.valeurMax = valeurMax; }
public int getValeur() { return valeur; }
public void setValeur(int valeur) { this.valeur = valeur; }
public int getTentative() { return tentative; }
public String recommencer() {
alea = (int)(Math.random()*valeurMax)+1;
tentative = 0;
valeur = 0;
test = false;
return "alea.xhtml";
}

public void calcul() {
if (tentative<tentativeMax) {
tentative++;
test = alea == valeur;
}
}
public String getRsultat() {
if (test) return "Bravo, vous avez trouv !";
if (tentative==tentativeMax) return "Dsol, vous avez perdu. La valeur rechercher est ";
if (tentative==0) return "Tentez votre chance";
else return "Non, ce n'est pas le bon chiffre, refaites un essai.";
}
public String getProgression() {
if (tentative==0 || test) return "";
return "Le nombre est plus "+(alea>valeur ? "grand" : "petit");
}
public int getAlea() { return alea; }
public boolean isFin() { return test || tentative == tentativeMax; }
}
1. Pour cette partie relative au modle, nous pouvons envisager plusieurs approches quant au nombre de beans grs prendre en compte. La
solution retenue ici est de n'utiliser qu'un seul bean. Du coup, le code est beaucoup plus volumineux que lors du projet prcdent, puisque ce
mme bean doit tre en relation avec deux vues diffrentes. Par ailleurs, le traitement raliser est plus consquent.
2. Il s'agit d'un bean CDI. Remarquez cette fois-ci la prsence de l'annotaion @Named. Pour sa mise en oeuvre avec Netbeans, nous retrouvons les
mmes botes de dialogue, si ce n'est la petite diffrence quant au choix de la porte de l'objet.
3. Lors de l'laboration d'un bean gr, nous devons retrouver, bien entendu, des attributs, pour sauvegarder des informations qui vont tre utiles lors
du passage d'une requte l'autre, des proprits (getters et setters) indispensables pour la communication directe avec les vues, et des mthodes
qui vont tre appeles pour raliser des traitements spcifiques ou pour naviguer entre les vues lorsque l'utilisateur clique sur les boutons de
soumissions.
4. La porte choisie ici est une porte de type session. Ce choix est important puisque lorsque nous rglons les valeurs limites dans la page de
configuration, il est impratif de conserver ces valeurs lorsque nous basculons vers la page correspondant au jeu. Pour les mmes raisons, par
exemple, il faut bien garder en mmoire le nombre alatoire tir pendant toute la phase du jeu.
5. Les attributs prsents dans ce bean, sont les valeurs limites valeurMax et tentativeMax, ala le nombre alatoire rechercher, la valeur propose par
l'utilisateur en cours de jeu, le nombre de tentative qui s'incrmente automatiquement en cours de jeu et enfin test qui dtermine si le nombre
propos par l'utilisateur est le bon.
6. Nous retrouvons la plupart des prorits en relation avec ces attributs. Toutefois, il n'existe pas de proprit relative l'attribut test. Ainsi, des
attributs peuvent exister sans qu'ils soient systmatiquement accessibles directement dans la vue. Cet attribut test reste utile lors des traitements
annexes.
7. A l'inverse, et c'est flagrant ici, nous pouvons proposer des proprits qui ne sont associes aucun attribut particulier parce que nous ne dsirons
pas conserver d'informations particulires. Elles ne sont utiles que pour l'instant prsent. C'est le cas des proprits en lecture seule, rsultat,
progression et fin, accessibles donc au travers des mthodes respectives getRsultat(), getProgression() et isFin(). Les deux premires proprits
servent pour l'affichage d'informations alors que la dernire permet de savoir si nous somme la fin du jeu.
8. Pour terminer avec ce bean, la mthode intressante, comme nous l'avons dj voqu dans ce chapitre, est la mthode recommencer() qui sera
sollicite chaque fois que nous devons dbuter le jeu, soit aprs la configuration (appel depuis configurer.xhtml), soit lorsque nous dsirons tout
simplement recommencer une partie (appel depuis alea.xhtml).
9. Cette mthode permet d'initialiser correctement tous les attributs afin que le jeu dbute dans de bonnes conditions, et surtout, quand tout est prt,
c'est la vue alea.xhtml qui est automatiquement appele au retour de la mthode. Cette requte est prise en compte par le contrleur qui s'occupe
effectivement de cette demande d'affichage. Il s'agit d'une navigation dynamique.
Feuille de style CSS
Pour ce projet galement, et pour tous les projets d'ailleurs, il est judicieux de proposer une feuille de style principale afin de bien sparer l'aspect visuel ainsi
que la charte graphique avec les fonctionnalits propres des composants de la vue. Ainsi, il sera trs facile par la suite de changer rapidement cet aspect pour en
proposer un autre plus adapt.
Rappelez-vous que cette feuille de style ne doit pas tre place n'importe o. Vous devez imprativement prvoir au moins un rpertoire bien
spcifique pour toutes les ressources annexes votre projet qui se nomme trs justement resources :
resources/<identifiant_ressource>
ou
META-INF/resources/<identifiant_ressource>
<identifiant_ressource> est form de plusieurs sous-rpertoire indiqus sous la forme :
[locale/ ] [nomBibliothque/ ] nomRessource [ /versionRessource]
Je rappelle que tous les lments entre crochets sont facultatifs. La dernire fois, j'avais propos de prendre en compte la bibliothque (css)
que je ne renouvelle pas ici :
resources/principal.css
principal.css
root {
display: block;
}
body {
background-color: orange;
font-weight: bold;
color: maroon;
}
.saisie {
text-align:right;
background-color:yellow;
font-weight:bold;
color:green;
width: 30px;
display: block;
}
.normal {
font-weight:bold;
}
h2, h3 {
background-color: yellow;
padding: 5px;
border: groove;
}
.progression {
color: blue;
}
.resultat {
border: groove;
padding-right: 3px;
}
Les vues configurer.xhtml et alea.xhtml
Dans le projet, nous disposons de deux vues :
1. La premire configurer.xhtml qui permet, comme son nom l'indique, de faire les rglages ncessaires sur les valeurs maximales savoir, la valeur
maximale du nombre recherche et le nombre de tentative maximum.
2. La deuxime alea.xhtml qui s'occupe de jeu proprement dit :
configurer.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Recherche d'un nombre alatoire</title>
</h:head>
<h:outputStylesheet name="principal.css" />

<h:body>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Recherche d'un nombre alatoire compris entre 1 et " styleClass="normal" />
<h:inputText value="#{nombre.valeurMax}" styleClass="saisie"/>
<h:outputText value="Nombre de tentative possibles " styleClass="normal"/>
<h:inputText value="#{nombre.tentativeMax}" styleClass="saisie"/>
</h:panelGrid>
<hr />
<h:commandButton value="Commencer le jeu" action="#{nombre.recommencer}" />
</h:form>
</h:body>
</html>
1. Cette page est relativement modeste. Nous retrouvons la mme ossature que lors du premier projet. Le fait d'avoir construit une feuille de style
spare permet d'allger considrablement la vue elle-mme.
2. Dans ce projet, encore plus que pour le premier, une feuille de style est vraiment intressante, puisqu'elle est utilise pour deux vues diffrentes.
Cela permet de factoriser les rglages ncessaires dans un mme endroit et d'viter ainsi les duplications de code.
3. La prise en compte de la feuille de style se fait toujours au moyen de la balise <h:outputStylesheet name="principal.css" />. Cette fois-ci toutefois,
l'attribut library n'est pas utilis puisque nous avons plac la feuille de style directement dans le rpertoire resources sans proposer de libraire
interne.
4. La grande nouveaut concerne la balise <h:panelGrid columns="2">. Ce composant est l'quivalent d'un panneau intermdiaire qui permet d'aligner
tous les autres composants qui se trouve l'intrieur, et dans ce cas prcis suivant deux colonnes.
5. Avec le composant <h:commandButton value="Commencer le jeu" action="#{nombre.recommencer}" />, lorsque l'utilisateur clique sur le bouton,
c'est la mthode recommencer() du bean CDI nombre qui est appele, et cette dernire comme nous l'avons vu, aprs avoir remis zro les attributs
concernant le jeu, demande au contrleur d'afficher la page alea.xhtml.
public String recommencer() {
alea = (int)(Math.random()*valeurMax)+1;
tentative = 0;
valeur = 0;
test = false;
return "alea.xhtml";
}
alea.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Recherche d'un nombre alatoire</title>
</h:head>

<h:outputStylesheet name="principal.css" />
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Votre nombre : " />
<h:inputText value="#{nombre.valeur}" styleClass="saisie" />
<h:outputText value="#{nombre.progression}" styleClass="progression" />
<h:outputFormat value="Tentative{0, choice, 0#|2#s} : ">
<f:param value="#{nombre.tentative}" />
</h:outputFormat>
<h:inputText value="#{nombre.tentative}" styleClass="saisie" disabled="true" />
</h:panelGrid>
<hr />
<h:commandButton value="Valider votre nombre" action="#{nombre.calcul}" disabled="#{nombre.fin}" />
&nbsp;
<h:commandButton value="Recommencer" action="#{nombre.recommencer}" />
&nbsp;
<h:commandButton value="Changer les valeurs limites" action="configurer.xhtml" />
<hr />
<h2>
<h:outputText value="#{nombre.rsultat}" />
<h:outputText value="#{nombre.alea}" styleClass="saisie" rendered="#{nombre.fin}" />
</h2>
</h:form>
</h:body>
</html>
1. Ici aussi, je vous propose quelques remarques. Sur cette dernire version de JSF, il n'est pas oblig de prendre systmatiquement une balise
<h:outputText value="Votre nombre : " />. Nous aurions pu crire directement Votre nombre : . Si vous avez prendre en compte des styles CSS, il
est alors intressant de les utiliser, comme ici <h:outputText value="#{nombre.progression}" styleClass="progression" />.
2. Le composant <h:outputFormat value="Tentative{0, choice, 0#|2#s} : "> permet de proposer d'afficher des textes paramtrs, comme ici de rajouter
un s partir de la deuxime tentative. A l'intrieur de ce composant, vous devez spcifier l'ensemble des paramtres qui sert de critre de calcul au
travers du composant <f:param value="#{nombre.tentative}" />.
3. Le bouton <h:commandButton value="Valider votre nombre" action="#{nombre.calcul}" disabled="#{nombre.fin}" /> peut tre gris, et donc non
actif, au moyen de l'attribut disabled, ici par exemple lorsque nous somme la fin du jeu.
4. Lorsque vous dsirez faire une navigation statique, c'est--dire lorsque vous dsirez atteindre une autre page sans faire de traitement prliminaire ou
sans condition particulire, il suffit simplement de prciser la page dans l'attribut action du composants <h:commandButton value="Changer les
valeurs limites" action="configurer.xhtml" />.
5. Enfin, il est possible d'afficher un composant sous certaines conditions, ceci galement trs simplement, au moyen de l'attribut rendered (prsent
sur tous les composants visuels). Par exemple, lorsque nous sommes la fin du jeu, nous pouvons montrer le nombre rechercher <h:outputText
value="#{nombre.alea}" styleClass="saisie" rendered="#{nombre.fin}" />.
Conclusion

Bibliothques de balises JSF
L'architecture JSF est conue pour tre indpendante de tout protocole ou langage marqueurs particulier et pour crire des applications pour les clients HTML qui
communiquent via HTTP. Une interface utilisateur pour une page web donne est cre en assemblant des composants qui fournissent des fonctionnalits spcifiques
afin d'interagir avec l'utilisateur (labels, cases cocher, etc.) - JSF met disposition un certain nombre de classes composants couvrant la plupart des besoins
classiques.
Une page est une arborescence de classes hritant de javax.faces.component.UIComponent ayant des proprits, des mthodes et des vnements. La racine de
l'arbre est une instance de UIViewRoot et tous les autres composants respectent une relation d'hritage.
Lors de la version prcdente, JSF proposait uniquement deux librairies de balises : core et HTML, la version JSF 2.0 couvre maintenant six librairies diffrentes
qui possdent plus d'une centaine de marqueurs spcifiques. Le tableau ci-dessous nous rappelle ces diffrentes librairies. Dans ce chapitre toutefois, nous nous
intresserons uniquement sur les bibliothques core et HTML.
URI
Prfixe
classique
Description
http://java.sun.com/jsf/html h Contient les composants et leurs rendus HTML (h:commandButton, h:inputText, etc.)
http://java.sun.com/jsf/core f Contient les actions personnalises indpendantes d'un rendu particulier (f:convertNumber,
f:validateDoubleRange, f:param, etc.)
http://java.sun.com/jsf/facelets ui Marqueurs pour le support des modles de page.
http://java.sun.com/jsf/composite composite Sert dclarer et dfinir des nouveaux composants personnaliss.
http://java.sun.com/jsp/jstl/core c Les pages Facelets peuvent ventuellement utiliser certains marqueurs issus de JSP (c:if, c:forEach et
c:catch).
http://java.sun.com/jsp/jstl/functions fn Les pages Facelets peuvent utiliser tous les marqueurs de fonctions issus de la technologie JSP.
Bibliothque core
La bibliothque core (coeur) contient des balises qui sont indpendante du rendu HTML. Elles sont utiles pour proposer des traitements et des rglages spcifiques
pour les balises relatives la vue (bibliothque HTML).
Balises Description
<f:attribute> Propose un attribut particulier (cl/valeur) sur une balise parente.
<f:param> Spcifie un paramtre particulier associ la chane paramtre propose par la balise parente.
<f:facet> Gestion d'une zone dlimite de la page Web.
<f:actionListener> Ajoute un vnement de type validation sur un composant parent.
<f:setPropertyActionListener> Propose une proprit sur un vnement de type validation associ un composant parent.
<f:valueChangeListener> Ajoute un vnement de type changement de valeur sur un composant parent.
<f:phaseListener> Ajoute un vnement de type changement de phase sur un composant parent.
<f:event> Ajoute un systme d'vnement sur un composant parent.
<f:converter> Ajoute un convertisseur personnalis sur un composant parent.
<f:convertDateTime> Ajoute un convertisseur prdfini de type date ou heure sur un composant parent.
<f:convertNumber> Ajoute un convertisseur prdfini numrique sur un composant parent.
<f:validator> Ajoute un validateur personnalis un composant parent.
<f:validateDoubleRange> Ajoute un valideur prdfini qui limite les valeurs numriques relles sur un composant parent.
<f:validateLength> Ajoute un valideur prdfini qui limite le nombre de caractres saisie sur un composant parent.
<f:validateLongRange> Ajoute un valideur prdfini qui limite les valeurs numriques entires sur un composant parent.
<f:validateRequired> Vrifie qu'une valeur est prsente sur un composant parent.
<f:validateRegex> Vrifie que la valeur saisie respecte une expression rgulire sur un composant parent.
<f:validateBean> Utilise un bean de validation qui impose un certain nombre d'lments prendre en compte.
<f:loadBundle> Prise en compte d'une ressource qui propose l'ensemble des messages paramtrs (gestion de la nationalit, par exemple).
<f:selectItems> Propose l'ensemble d'lments qui vont remplir les radios boutons, les cases cocher, la liste droulante, etc.
<f:selectItem> Propose un lment spcifique.
<f:verbatim> Permet de donner le texte qui possde des balises sans interprtation particulire.
<f:viewParam> Dfini un paramtre pour la vue qui sera initialis l'aide du paramtre de la requte.
<f:ajax> Permet d'implmenter des commandes ajax.
<f:view> Utile si nous dsirons prendre en compte la nationalit ou la gestion vnementielle de phase.
Nous allons aborder certains de ces marqueurs afin d'expliquer leurs fonctionnement internes :
Attributs, paramtres et facettes
Les balises <f:attribute>, <f:param> et <f:facet> sont gnralement proposes pour rajouter des informations sur un composant parent. Chaque composant peut
enregistrer un nombre arbitraire de paires nom / valeur.
1. <f:attribute> : Ainsi, l'aide de cette balise, vous pouvez proposer un attribut particulier dans la page web (la vue) qui sera ensuite exploite par le
modle pour raliser un traitement spcifique :
<h:outputText value="#{agent.tlphone}">
<f:converter converterId="numroTlphone" />
<f:param name="sparateur" value="-" />
</h:outputText>
Les attributs sont gnralement utiles pour les convertisseurs personnaliss. Une fois que l'attribut spcifi est associ la balise parente,
le convertisseur est capable de le retrouver aisment, comme ceci :
sparateur = (String) component.getAttributes().get("sparateur");

// component est issu de la mthode String getAsString(FacesContext context, UIComponent component, Object value)
2. <f:param> : Cette balise permet galement de dfinir une paire nom / valeur. Le nom correspond cette fois-ci plutt un numro, suivant l'ordre o
nous plaons chacunes des balises <f:param>. Typiquement, cette balise peut tre associe la balise parente <h:outputFormat> comme nous
l'avons dj utilise dans le projet prcdent :
<h:outputFormat value="Tentative{0, choice, 0#|2#s} : ">
<f:param value="#{nombre.tentative}" />
</h:outputFormat>
Dans ce cas, il n'existe qu'un seul paramtre, correspondant donc la position 0, et dont la valeur rcupre dans la proprit tentative de
nombre est soumise la balise parente afin que son valuation dtermine la mise en place du pluriel ou pas.
3. <f:facet> : Cette balise est utilise dans des cas trs particulier pour spcifier une apparence adapte. Ainsi, par exemple, dans une page web, nous
retrouvons presque systmatiquement deux facettes nommes head et body. Typiquement, nous utilisons cette balise presque uniquement pour
proposer des facettes diffrentes un tableau (<h:dataTable>). Ainsi, nous pouvons proposer un tableau uniforme, ou avec une en-tte, ou avec un
pied, ou avec un titre, ou bien avec une combinaison de toutes ces possibilits. Pour obtenir ces diffrents aspects, vous placez respectivement les
valeurs header, footer ou caption dans cette balise <f:facet> suivant le cas.
<h:dataTable value="#{auteurs}" var="lment" headerClass="inverse" columnClasses="ligne">
<h:column>
<f:facet name="header">Nom</f:facet>
#{lment.nom}
</h:column>
<h:column>
<f:facet name="header">Prnom</f:facet>
#{lment.prnom}
</h:column>
</dataTable>
Dans ce tableau, par exemple, nous plaons une en-tte d'une couleur diffrente que les autres lignes du tableau, dont la premire
colonne sera intitul Nom et la deuxime Prnom. Par ailleurs, et de faon automatique, la facette de type header permet de centrer dans
la colonne la valeur que nous lui proposons.
Bibliothque html
Cette bibliothque intgre cette fois-ci des composants visuels, qui assurent donc le rendu de la page web. Nous pouvons les regrouper par catgories :
1. Structure de la page HTML (head, body, form, outputStylesheet, outputScript)
2. Dispositions (panelGrid, panelGroup)
3. Tables (dataTable et column)
4. Les entres : (input...)
5. Les sorties (output...)
6. Les images (graphicImage)
7. Les commandes (commandButton et commandLink)
8. Les requtes GET HTTP (button, link, outputLink)
9. Les slections (checkbox, listbox, menu, radio)
10. Messages d'erreur (message, messages)
Nous allons prendre le temps de bien analyser chacun de ces groupes de balises. Au pralable, je vous invite consulter l'ensemble des attributs qui leurs sont
communs. Il existe trois types d'attribut :
1. Les attributs de base,
2. Les attributs qui ont leurs correspondances HTML,
3. Les attributs associs aux vnements DHTML.
Attributs de base
Dans le tableau ci-dessous, nous dcouvrons l'ensemble des attributs qui sont partags par la majorit des marqueurs JSF.
Attributs Description
id Permet d'identifier le composant pour interagir avec un autre.
binding Lie ce marqueur (ce composant dans sa globalit) directement avec le bean gr, et permet donc une interaction en coulisse.
rendered Attribut trs intressant qui permet d'afficher ou pas la balise (quivalent d'un if). Valeurs possibles true ou false.
value Attribut certainement le plus utilis, qui permet d'tre en relation directe avec une proprit particulire du bean gr dtermin
par une expression EL (#{bean.proprit}).
valueChangeListener Un couteur spcifique qui entre en action lors d'un changement de valeur. La mthode dsigne dans cet attribut est alors
automatiquement sollicite.
converter Mise en relation avec un convertisseur personnalis (classe qui implmente l'interface Converter) et qui permet de passer d'une
chane de caractres (seule type compatible avec le protocole HTTP) vers un autre type quelconque et vice versa.
validator Mise en relation avec un validateur personnalis (classe qui implmente l'interface Validator, ou ventuellement une mthode
avec une signature spcifique) qui permet d'envoyer la valeur dsigne dans l'attribut value au bean gr (qui travaille en
coulisse) que si la valeur est correcte.
required Une valeur est imprativement requise dans ce champ pour passer la phase de validation.
converterMessage,
validatorMessage,
requiredMessage
Messages personnaliss qui s'affichent automatiquement (en relation avec les balises <h:message> ou <h:messages>) lorsque un
problme survient lors de la phase de conversion, de validation ou lorsque q'une valeur de saisie est oublie.
1. Tous les composants, quels qu'ils soient, peuvent utiliser les attributs id, binding et rendered que nous allons tout de suite analyser.
2. Les attributs value et converter permettent, de concert, de spcifier comment la proprit du bean propose puisse tre automatiquement convertie
sous forme de chane de caractres, afin d'tre transmis correctement par le protocole HTTP pour la vue, et comment, en coulisse avec le modle,
manipuler cette proprit par le bean gr pour travailler directement avec le type adquat.
3. Enfin, les attributs validator, required et valueChangeListener sont disponibles pour les composants de saisie (Entres) qui ralisent un contrle des
valeurs saisies afin de faire ragir ventuellement l'oprateur pour qu'il corrige le tir afin que ces dernires soient finalement considres comme
valides pour le traitement souhait.
Identification et liaisons entre composants
L'attribut polyvalent id permet de raliser les choses suivantes :
1. L'accs au composant identifi par un autre composant de la page web. L'exemple trs frquent consiste identifier un composant d'entre afin
d'afficher un message d'erreur adapt au cas o la saisie ne serait pas correcte :
<h:inputText value="#{conv.euro}"
id="euro"
converterMessage="Il faut une valeur montaire"
validatorMessage="Uniquement les nombres positifs"
required="true"
requiredMessage="Prcisez votre valeur montaire">

<f:convertNumber type="currency" currencySymbol=""/>
<f:validateDoubleRange minimum="0.0" />
</h:inputText>

<h:message for="euro" styleClass="erreur"/>
2. Obtenir en coulisse les rfrences de ce composant dans le code Java du bean gr. Par exemple, si nous dsirons accder au composant dsign
par euro au travers d'un couteur, voici ce que nous pouvons crire :
UIComponent composant = event.getComponent().findComponent("euro");
Attention, pour que ce code soit exploitable, le composant qui gnre l'vnement doit se trouver dans le mme formulaire (<h:form>)
que le composant identifi, sinon le composant ne sera pas accessible.
3. Accs aux lments HTML au travers de scripts.
Il existe une autre dmarche pour accder un composant de la vue depuis le code Java. Il suffit de dfinir une proprit dans le modle et ensuite de
spcifier l'attribut binding du composant en connexion avec cette proprit particulire.
<h:inputText binding="#{beanGr.proprit}" ... />
L'attribut binding est spcifi l'aide d'une expression EL. Cette expression, comme d'habitude fait rfrence une proprit particulire du bean gr,
qui d'ailleurs doit tre la fois accessible en lecture et en criture.
private UIComponent proprit = new UIInput(); // cration d'un objet qui correspond au type du composant visuel reprsenter
public UIComponent getProprit() { return proprit; }
public void setProprit(UIComponent proprit) { this.proprit = proprit; }
Nous pourrions nous poser la question sur l'intrt d'un tel attribut binding puisque value est gnralement suffisant. Dans des cas trs particulier, il
peut tre intressant de faire rfrence au composant de la vue dans son ensemble plutt que de rester uniquement sur la proprit, interne donc au
bean. Nous pourrions du coup envisager de faire du traitement spcifique sur ce composant visuel pour faire en sorte qu'il soit par exemple non
ditable, non visible, gris, etc. directement depuis le bean gr.
Effectivement, tous les composant visuels sont avant tout des classes avec donc leurs propres mthodes. il suffit de faire appel ces mthodes pour
changer le comportement de ces lments visuel, en coulisse, directement depuis le modle.
Valeurs, convertisseurs et validateurs
Les entres, les sorties, les commandes et tables de donnes manipulent toutes des valeurs. L'attribut value permet d'tre en relation avec ces valeurs. Il peut
s'agir d'une valeur littrale comme d'une valeur issue d'une proprit :
<h:commandButton value="Intitul du bouton" ... />
<h:inputText value="#{beanGr.proprit}" ... />
1. L'attribut converter, propos pour les balises d'entre et de sortie, permet de rattacher un convertisseur personnalis un composant.
2. Les balises d'entre peuvent galement propose l'attribut validator afin de rattacher un validateur personnalis un composant.
3. Ces convertisseurs et validateurs sont bien utiles afin d'viter que le bean gr ne rentre dans sa phase de traitement d'informations tant que les
valeurs proposes ne sont pas valides.
Rendu conditionnel
Vous pouvez utiliser l'attribut rendered pour inclure ou exclure des composants dans votre page web, d'avoir ainsi un rendu conditionnel. Par exemple, nous
pourrions afficher un bouton de dconnexion que si nous sommes sr que l'utilisateur s'est dj logger :
<h:commandButton value="Deconnexion" rendered="#{utilisateur.connect}" action="#{utilisateur.seDconnecter}" />
<h:inputText... />
La condition du rendu peut s'appliquer sur un groupe de composants, au travers des balises <h:panelGrid> ou <h:panelGroup> qui possdent cet
attribut rendered.
<h:pannelGrid columns="2" rendered="#{bean.ongletSlectionn == 'vido'}">
<h:outputText... />
<h:commandButton... />
...
</h:pannelGrid>
Attributs HTML
Ces types d'attributs sont particuliers puisqu'ils ne sont pas interprts par les composants JSF mais sont directement traduits dans les balises HTML
correspondantes. Il s'agit exactement des mmes attributs qui sont proposs par les balises HTML standard.
<h:inputText size="25" value="#{bean.proprit}" /> // code propos en JSF
...
<input size="25" type="text" ... /> // balise gnre automatiquement par le systme pour l'envoyer ensuite au client
Ainsi, par exemple, si nous proposons l'attribut size une balise JSF, nous la retrouvons ensuite intgralement, sans interprtation particulire, dans
la balise HTML quivalente. Rappelez vous que la vue JSF reste sur le serveur et que le document envoy est une page web avec des balises HTML
standard (le client n'a besoin d'installer de pluggin particulier, un simple navigateur suffit).
Attributs Description
alt Prvoit un texte alternatif dans le cas o une image par exemple n'est pas prsente.
border Largeur de bordure en pixel.
dir Direction du texte. Les valeurs valides sont "LTR" (Left To Right) et "RTL" (Right To Left).
disabled Permet de gris un lment pour le rendre inactif l'image des zones de saisie et des boutons de commande.
maxlength Spcifie le nombre maximum de caractres possible sur une zone de saisie.
readonly Empche de raliser une dition sur une zone de saisie.
rows Spcifie le nombre de lignes pour une zone de texte.
size Taille pour une zone de saisie.
style Possibilit d'introduire un style CSS uniquement sur cette balise.
styleClass Propose un style CSS prdfini dans une feuille de style spare.
title Description du marqueur qui typiquement est traduit sous forme de bule d'aide par les navigateurs.
width Largeur en pixels de ce composant.
Styles CSS
Nous pouvons donc introduire des styles CSS, soit directement (attribut style), soit partir d'une dclaration dj faite antrieurement (attribut
styleClass) qui influence, bien entendu, le rendu du composant.
<h:inputText styleClass="bordure" value="#{bean.proprit}" />
<h:inputText style="border: thin solid blue" value="#{bean.proprit}" />
Gestion des ressources
La plupart des composants ont besoin de ressources externes pour s'afficher correctement : <h:graphicImage> a besoin d'une image, <h:commandButton>
peut galement afficher une image pour reprsenter le bouton, <h:outputScript> rfrence un fichier JavaScript et surtout les composants peuvent galement
appliquer des styles CSS.
Avec JSF, une ressource est un lment statique qui peut tre transmis aux lments afin d'tre affich (images) ou trait (CSS) par le navigateur. JSF
2.0 permet d'assembler directement les ressources dans un fichier jar spar, avec un numro de version et une locale, et de les placer la racine de
l'application web, sous le rpertoire suivant :
resources/<identifiant_ressource>
ou
META-INF/resources/<identifiant_ressource>
<identifiant_ressource> est form de plusieurs sous-rpertoire indiqus sous la forme :
[locale/ ] [nomBibliothque/ ] nomRessource [ /versionRessource]
Tous les lments entre crochets sont facultatifs. La locale est le code du langage, suivi ventuellement d'un code de pays (en, en_US, pt,
pt_BR). Comme l'indique cette syntaxe, vous pouvez ajouter un numro de version la bibliothque ou la ressource elle-mme.
Voici quelques exemples :
resources/css/principal.css
resources/images/logo.png
resources/javascript/jsf.js
Voici maintenant comment prendre en compte ces diffrentes ressources :
<h:outputStylesheet library="css" name="principal.css" />
<h:outputScript library="javascript" name="jsf.js" target="head" />
<h:graphicImage library="images" name="logo.png" />
Evnements DHTML
Il est possible de rajouter un comportement plus dynamique sur vos pages web, comme des animations ou la prise en compte en temps rel d'un certain
nombre d'vnements. C'est ce que nous appelons communment le DHTML. En ralit, en coulisse, ds que nous voquons des pages DHTML, nous faisons
rfrence du javascript.
Tous ces vnement javascript sont disponibles sur chacun des composants JSF au travers d'attributs spcifiques dont voici la liste. Vous devez
prciser ensuite l'action que vous dsirez raliser l'issu de ces vnements.
Attributs Description
onblur L'lment perd le focus.
onchange La variable de la zone de saisie change de valeur.
onclick Prise en compte du clic de la souris.
ondblclick Prise en compte du double clic de la souris.
onfocus L'lment reprend le focus.
onkeydown L'oprateur est en train d'appuyer sur une touche.
onkeypress L'oprateur tape sur une touche.
onkeyup L'oprateur relache une touche.
onload Au moment o la page est charge.
onmousedown En train d'appuyer sur un bouton de la souris.
onmousemove La souris se dplace sur l'lment.
onmouseout La souris sort de la zone de l'lment.
onmouseover La souris passe au dessus de l'lment.
onmouseup On relache un bouton de la souris
onreset Le formulaire est remise zro.
onselect Texte slectionn dans une zone de saisie.
onsubmit Le formulaire est envoy pour traitement.
onunload Au moment o nous quittons la page en cours.
Structure de la page HTML (<h:head>, <h:body>, <h:form>, <h:outputScript>, <h:outputStylesheet>)
Tous ces marqueurs n'ont pas de reprsentation graphiques mais possdent un quivalent HTML (voir tableau ci-dessous). Bien que les marqueurs natifs
HTML puissent tre utiliss directement sans problme, les marqueurs JSF possdent des attributs supplmentaires qui facilitent le dveloppement.
Vous pouvez, par exemple, ajouter une bibliothque JavaScript l'aide du marqueur HTML Standard <script type="text/JavaScript">, mais le
marqueur <h:outputScript library="javascript" name="jsf.js" target="head" /> de JSF permet d'utiliser la nouvelle gestion des ressources, comme nous
venons de le dcouvrir plus haut.
Balises Description
<h:body> Gnre un lment <body> HTML.
<h:head> Gnre un lment <head> HTML.
<h:form> Gnre un lment <form> HTML.
<h:outputScript> Gnre un lment <script> HTML.
<h:outputStylesheet> Gnre un lment <link> HTML.
<h:outputStylesheet> Gnre un lment <link> HTML.
Typiquement, les applications web fonctionnent en soumettant des requtes issues d'un formulaire. JSF n'chappe pas cette rgle de base et doit
proposer au moins une balise <h:form>.
1. Bien que la balise <form> du HTML standard propose les attributs method et action qu'il est ncessaire de spcifier, le marqueur quivalent JSF
<h:form> n'a pas besoin de ce genre d'informations.
2. Il faut dire que dans le cas de JSF, l'attribut action n'a pas de sens puisque le traitement souhait par les requtes issues de ce formulaire peuvent
ventuellement tre ralis par plusieurs beans grs.
3. Comme nous pouvons sauvegarder l'tat complet d'un ou plusieurs beans grs chez le client, une option qui s'implmente au travers de champs
cachs, les soumissions de formulaire ne peuvent tre effectues par la mthode GET HTTP.
4. Effectivement, le contenu de ces champs cachs peut dpasser largement les capacits du buffer relatif l'envoi de la requte, aussi les formulaires
JSF sont toujours implments l'aide des mthodes POST HTTP.
Grilles et tableaux
Les donnes doivent souvent tre affiches sous forme de tableau. JSF fournit donc le marqueur <h:dataTable> permettant ainsi de parcourir une liste
d'lments (dont la taille est variable) afin de gnrer automatiquement un tableau. Les tableaux peuvent galement servir de gestion de disposition des
composants afin de crer une interface utilisateur sous forme de grille. Dans ce cas, vous pouvez utiliser les marqueurs <h:panelGrid> et <h:panelGroup>
pour disposer les composants votre guise.
Balises Description
<h:dataTable> Reprsente un ensemble de donnes qui seront affichs dans un lment <table> HTML.
<h:column> Produit une colonne de donnes dans un composant <h:dataTable>.
<h:panelGrid> Produit galement un lment <table> HTML.
<h:panelGroup> Conteneur de composants pouvant s'imbriquer dans un <h:panelGrid>.
Les tableaux dynamiques composs de la balise <h:dataTable> et des balises <h:column> feront parti d'un chapitre part entire au cours de cette
tude.
A la diffrence de <h:dataTable>, le marqueur <h:panelGrid> n'utilise pas de modle de donnes sous-jacent pour produire des lignes de donnes -
c'est un conteneur permettant d'insrer les autres composants JSF dans une grille de lignes et de colonnes.
Vous pouvez prciser le nombre de colonnes que comportera cette grille de disposition l'aide de l'attribut column. <h:panelGrid> dterminera
automatiquement le nombre de lignes ncessaire suivant le nombre de composants introduits. Il place alors les composants dans l'ordre prcis de la
gauche vers la droite et du haut vers le bas.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:body style="background-color: orange">
<h:form>
<h:outputText value="Identification" />
<hr />
<h:panelGrid columns="2" border="1">
<h:outputText value="Nom :" />
<h:inputText value="" />
<h:outputText value="Prnom :" />
<h:inputText value="" />
<h:outputText value="Mot de passe :" />
<h:inputSecret value="" />
</h:panelGrid>
<hr />
<h:commandButton value="Connexion" />
</h:form>
</h:body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:body style="background-color: orange">
<h:form>
<h:outputText value="Identification" />
<hr />
<h:panelGrid columns="2">
<h:outputText value="Nom :" />
<h:inputText value="" />
<h:outputText value="Prnom :" />
<h:inputText value="" />
<h:outputText value="Mot de passe :" />
<h:inputSecret value="" />
</h:panelGrid>
<hr />
<h:commandButton value="Connexion" />
</h:form>
</h:body>
</html>
Pour combiner plusieurs composant dans la mme colonne, utilisez un <h:panelGroup> qui produira ses fils comme un seul et unique composant.
Vous pouvez galement dfinir un en-tte et un pied l'aide du marqueur spcial <f:facet>.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<style type="text/css">
body {background-color: green; color: yellow; }
.ligne {background-color: #005500; }
.saisie {background-color: greenyellow; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" styleClass="ligne">
<f:facet name="header">
<h:outputText value="Identification" />
</f:facet>
<h:outputText value="Nom :" />
<h:inputText value="" styleClass="saisie"/>
<h:outputText value="Prnom :" />
<h:inputText value="" styleClass="saisie" />
<h:outputText value="Mot de passe :" />
<h:panelGroup>
<h:inputSecret value="" styleClass="saisie" />
<h:outputText value=" (4 mini)" />
</h:panelGroup>
<f:facet name="footer">
<h:commandButton value="Connexion" />
</f:facet>
</h:panelGrid>
</h:form>
</h:body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<style type="text/css">
body {background-color: green; color: yellow; }
.cadre {background-color: #005500; }
.ligne {background-color: #007000; }
.saisie {background-color: greenyellow; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" rowClasses="ligne"
footerClass="cadre"
headerClass="cadre">
<f:facet name="header">
<h:outputText value="Identification" />
</f:facet>
<h:outputText value="Nom :" />
<h:inputText value="" styleClass="saisie"/>
<h:outputText value="Prnom :" />
<h:inputText value="" styleClass="saisie" />
<h:outputText value="Mot de passe :" />
<h:panelGroup>
<h:inputSecret value="" styleClass="saisie" size="12"/>
<h:outputText value=" (4 mini)" />
</h:panelGroup>
<f:facet name="footer">
<h:commandButton value="Connexion" />
</f:facet>
</h:panelGrid>
</h:form>
</h:body>
</html>
Il est possible de rajouter des styles personnaliss sur diffrentes parties
de la table :
1. La table dans son entier avec l'attribut styleClass.
2. L'entte avec l'attribut headerClass.
3. Le pied avec l'attribut footerClass.
4. Les lignes avec l'attribut rowClasses.
5. Les colonnes avec l'attribut columnClasses.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<style type="text/css">
body {background-color: green; color: yellow; }
.cadre {background-color: #005500; }
.ligne {background-color: #007000; }
.saisie {background-color: greenyellow; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" rowClasses="ligne, cadre"
footerClass="cadre" headerClass="cadre">
<f:facet name="header">
<h:outputText value="Identification" />
</f:facet>
<h:outputText value="Nom :" />
<h:inputText value="" styleClass="saisie"/>
<h:outputText value="Prnom :" />
<h:inputText value="" styleClass="saisie" />
Vous remarquez que les attributs rowClasses et columnClasses possdent
un "s" la fin, contrairement aux autres. Cette particularit est importante
puisqu'il est possible de proposer plusieurs styles pour le mme attribut.
L'intrt ici est de permettre une alternance de couleurs entre les lignes
ou les colonnes l'image de certains listings.
<h:outputText value="Mot de passe :" />
<h:panelGroup>
<h:inputSecret value="" styleClass="saisie" size="12"/>
<h:outputText value=" (4 mini)" />
</h:panelGroup>
<f:facet name="footer">
<h:commandButton value="Connexion" />
</f:facet>
</h:panelGrid>
</h:form>
</h:body>
</html>
Les entres
les entres sont des composants qui affichent leur valeur courante (actuelle) et permettent l'utilisateur de saisir diffrentes informations textuelles. Il peut
s'agir de champs de saisie, de zone de texte ou de composants pour entrer un mot de passe ou des donnes caches.
Balises Description
<h:inputHidden> Reprsente un lment d'entre HTML de type cach (non affich).
<h:inputSecret> Reprsente un lment d'entre HTML de type mot de passe. Pour des raisons de scurit, tout ce qui est saisi ne s'affiche pas (des
points apparaissent la place de chaque caractre introduit), sauf si la proprit redisplay vaut true.
<h:inputText> Reprsente un lment d'entre HTML de type texte.
<h:inputTextarea> Reprsente une zone de texte HTML.
De nombreuses pages web contiennent des formulaires pour que l'utilisateur puisse saisir des donnes ou se connecter en fournissant un mot de
passe. En outre les composants d'entre utilisent plusieurs attributs permettant de modifier leur longueur, leur contenu ou leur aspect.
Attributs Description
cols Nombre de colonnes, utile uniquement pour la balise <h:inputTextarea>.
immediate Permet de passer outre les phases de conversion et de validations.
redisplay Uniquement pour la balise <h:inputSecret>. Lorsque cet attribut est valid (true), la valeur du champ est raffiche au
recharchement de la page.
required Une valeur est imprativement requise dans ce champ pour passer la phase de validation.
rows Nombre de lignes, utile uniquement pour la balise <h:inputTextarea>.
label Description du composant lorsqu'un message d'erreur est sollicit. Ne s'applique pas la balise <h:inputHidden>.
valueChangeListener Un couteur spcifique qui entre en action lors d'un changement de valeur.
<h:inputHidden value="#{bean.valeurCacheRcupre}" />
<h:inputSecret value="#{bean.motDePasse}" maxlength="8" />
<h:inputText value="#{bean.proprit}" />
<h:inputText value="#{bean.proprit}" size="40" />
<h:inputTextarea value="#{bean.proprit}" rows="5" cols="20" />
1. Tous les composants possdent un attribut value pour fixer leur valeur par dfaut, et surtout pour enregistrer la valeur saisie dans la proprit
choisie. Ce qui sous-entend que la proprit doit imprativement tre accessible la fois en lecture et en criture. Les attributs immediate, required
et valueChangeListener existent pour tous ces marqueurs d'entre.
2. L'attribut maxLength permet de s'assurer que le texte ne dpasse pas une longueur donne et l'attribut size modifie la taille par dfaut du
composant. (voici ci-dessous l'apparence du code propos).
3.
4. Trois attributs sont spcifiques un seul marqueur. Il s'agit de cols et rows qui permettent de proposer une dimension (un nombre de lignes et de
colonnes) la balise <h:inputTextArea>. Le dernier attribut est redisplay qui est ventuellement utilis par la balise <h:inputSecret>. Cet attribut
prend une valeur boolenne qui permet, en cas de validation, de retenir le mot de passe pour qu'il soit automatiquement reproposer (de faon
cach, bien videmment) la prochaine demande de connexion.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:body style="background-color: green; color: yellow; font-weight: bold">
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Lecture seule :" />
<h:inputText value="#{test.valeur}" readonly="true"/>
<h:outputText value="Raffichage du mot de passe :" />
<h:inputSecret value="#{test.motPasse}" redisplay="true" />
<h:outputText value="Pas de raffichage :" />
<h:inputSecret value="#{test.motPasse}" redisplay="false" />
<h:outputText value="Style personnalis :" />
<h:inputText value="#{test.valeur}"
style="background: yellow; color: green"/>
<h:outputText value="Taille limite :" />
<h:inputText value="#{test.valeur}" size="5"/>
<h:outputText value="Nombre de caractres limits :" />
<h:inputText value="#{test.valeur}" size="10" maxlength="6" />
</h:panelGrid>
<hr />
<h:commandButton value="Soumettre" />
</h:form>
</h:body>
</html>
JSF supporte les champs cachs l'aide du marqueur <h:intputHidden>. Les champs cachs sont souvent utiliss avec des actions JavaScript pour
interagir avec le serveur.
Les sorties
Les composants de sortie affichent une valeur qui peut ventuellement avoir t obtenue partir d'un bean gr, une valeur issue d'une expression EL
quelconque ou un simple texte littral. L'utilisateur ne peut pas modifier ce contenu car il est bien entendu en lecture seule.
Balises Description
<h:outputLabel> Gnre une balise <label> HTML.
<h:outputLink> Gnre une balise <a> HTML.
<h:outputText> Gnre tout simplement un texte littral.
<h:outputFormat> Gnre un texte littral paramtr.
<h:graphicsImage> Gnre une balise <img> HTML.
La plupart des pages web affichent du texte. Pour ce faire, vous pouvez utiliser des balises HTML classiques mais, grce EL, les marqueurs de sortie
de JSF permettent d'afficher le contenu d'une proprit lie un bean gr.
<h:outputText>
La balise <h:outputText> est certainement le marqueur le plus simple de JSF. Avec une simple poigne d'attributs, il ne gnre aucune balise HTML
particulire. Il produit un simple texte. Il existe toutefois une seule exception cette rgle. En effet, lorsque nous demandons prendre en compte un style
CSS, au travers des attributs style ou styleClass, la balise <h:outputText> gnre alors, comme nous nous en doutons, une balise <span>.
Depuis la version JSF 2.0, vous n'tes pas oblig d'utiliser la balise <h:outputText> pour afficher le contenu d'une proprit. Il est possible de s'en
passer et d'crire directement l'expression EL : #{bean.proprit}, par exemple. Vous devez toute de mme utiliser cette balise dans les circonstances
suivantes :
1. Pour gnrer une sortie avec la prise en compte de styles CSS.
2. Lorsque vous utilisez un panneau pour tre sr que le texte soit considr comme une cellule part entire.
3. Pour gnrer imprativement une balise HTML.
Les balises <h:outputText> <h:outputLabel> et <h:outputFormat> possdent un attribut trs particulier qui n'existe que pour ces trois marqueurs. Il
s'agit de l'attribut escape, qui par dfaut prend la valeur true, et qui permet automatiquement de transformer les caractres < > et & respectivement en
&lt; &gt; et &amp; afin de conserver l'affichage original. Vous devez positionner cet attribut false si vous dsirez gnrer des balises HTML par
programme.
<h:outputFormat>
La balise <h:outputFormat> permet de composer des messages paramtrs l'image de la classe MessageFormat. En interne, la balise <h:outputText> utilise
effectivement cette classe. Vous devez ensuite spcifier vos diffrents paramtres l'aide des balises <f:param>.
<h:outputFormat value="Il reste {0} jour{0, choice, 0#|2#s}" style="color: green">
<f:param value="#{gestionEmprunts.emprunt.joursRestant}" />
</h:outputFormat>
Dans ce code, le message utilise un seul paramtre qui dtermine le nombre de jour restant avant de rendre le document emprunt dans une
bibliothque. Rappelez-vous que la numrotation du paramtre commence toujours par 0. Remarquez au passage comment faire en sorte que le
pluriel soit pris en compte.
<h:outputLabel>
La balise <h:outputLabel> est la reprsentation exacte de l'quivalent <label> du HTML. Cette balise meconnue permet d'amliorer grandement l'ergonomie
de vos formulaires. Elle permet, par exemple, de cocher un lment de type radio bouton ou de case cocher par un clic sur le texte qui lui est joint.
De faon plus gnrale, la balise <h:outputLabel> permet de rattacher une information un contrle par le biais d'une tiquette. Comme autre
exemple, elle peut tre utilis dans les formulaires pour mettre en relation une zone de saisie et son descriptif. Dans la pratique, cette relation
entre <h:outputLabel> et <h:inputText> peut se faire en liant l'attribut for du LABEL l'attribut id de l'lment INPUT.
<h:outputLabel value="Identifiant : " for="identifiant" />
<h:inputText value="#{test.identifiant}" id="identifiant" />
<h:outputLabel value="Mot de passe : " for="passe" />
<h:inputSecret value="#{test.motPasse}" id="passe" />
<h:inputSecret value="#{test.motPasse}" id="passe" />
<h:selectBooleanCheckbox id="choix">
<h:outputLabel value="Slectionner le texte ou la case" for="choix" />
</h:selectBooleanCheckbox>
Les graphiques
Il n'existe qu'un seul composant pour afficher les images <h:graphicsImage>. Ce marqueur gnre un lment <img> HTML pour afficher une image que les
utilisateurs n'auront pas le droit de manipuler. Ses diffrents attributs permettent de modifier la taille de l'image, de l'utiliser comme image cliquable, etc. Une
image peut tre lie une proprit d'un bean gr et provenir d'un fichier sur le systme ou d'une base de donnes.
Vous pouvez spcifier la localisation de l'image avec les attributs url ou value relativement au placement de l'image dans votre application web. De
plus, depuis la version 2.0 de JSF, il est souhaitable de placer vos images comme ressource dans une librairie prvue cet effet.
<h:graphicsImage library="images" name="logo.gif" />
<h:graphicsImage url="/resources/images/logo.gif" />
<h:graphicsImage value="#{bean.logo}" />
Ces trois exemples ralise en ralit le mme traitement, celui d'afficher le logo qui se trouve dans le sous-rpertoire images qui se trouve lui-mme
dans le rpertoire resources.
Les commandes - boutons et hyperliens
Les commandes sont les contrles sur lesquels l'utilisateur peut cliquer pour dclencher une action. Ces composants sont gnralement reprsents sous
forme de boutons ou de liens hypertextes spcifis par les marqueurs suivants :
Balises Description
<h:commandButton> Reprsente un lment HTML pour un bouton de type submit ou reset. La mthode HTTP de la requte est de type POST.
<h:commandLink> Reprsente un lment HTML pour un lien agissant comme un bouton submit. Ce composant doit tre plac dans un formulaire. La
mthode HTTP de la requte est de type POST.
<h:button> Ce composant est similaire au marqueur <h:commandButton> mais c'est La mthode GET HTTP qui est propse pour soumettre la
requte.
<h:link> Ce composant est similaire au marqueur <h:commandLink> mais c'est La mthode GET HTTP qui est propse pour soumettre la
requte.
<h:outputLink>
Gnre une balise <a> HTML. A la diffrence de <h:commandLink>, il n'est pas ncessaire de placer cette balise dans un
formulaire, il s'agit d'un simple lien statique sans interprtation particulire pas JSF, ni d'appel de mthode spcifique du bean
gr.
1. Par dfaut, un <h:commandButton> est de type submit. A l'image du HTML, nous pouvons prvoir un bouton de rinitialisation du formulaire au
moyen de l'attribut type.
2. L'attribut value permet de renseigner l'intitul du bouton. Vous avez aussi la possibilit d'utiliser une image comme bouton. Dans ce cas ne prenez
plus l'attribut value, mais plutt l'attribut image pour indiquer le chemin d'accs du fichier image que vous souhaitez afficher.
3. Les boutons et les liens possdent tous les deux un attribut action qui permet soit de naviguer vers une nouvelle page, soit d'appeler une mthode
spcifique du bean gr afin de raliser un traitement particulier (qui elle-mme peut proposer une navigation vers une autre page).
<h:commandButton value="Valider votre commande" action="#{bean.validation}" />
<h:commandButton value="Rinitialiser le formulaire" type="reset" />
<h:commandButton image="image.png" action="page.xhtml" />
<h:commandLink value="Naviguer vers votre nouvelle page" action="#{bean.mthode}" />
<h:commandLink value="Naviguer vers votre nouvelle page" action="page.xhtml" />
1. Les balises <h:commandButton> et <h:commandLink> sont certainement les composants principaux que nous utiliserons pour la navigation dans
une application JSF, soit respectivement sous l'apparence d'un bouton ou sous l'apparence d'un hyperlien. Lorsque un bouton ou un lien est activ,
une requte POST est soumise et les donnes du formulaire sont envoyes au serveur d'applications.
2. JSF 2.0 introduit les composants <h:button> et <h:link>. Ces balises donnent le mme rendu que les prcdentes, savoir un bouton et un lien, mais
lorsque nous cliquons sur un de ces composant, c'est cette fois-ci une requte GET qui est alors soumise au serveur d'applications.
3. La balise <h:outpuLink> quant elle gnre une simple balise <a> HTML qui permet alors de pointer vers une ressource comme une image ou une
autre page web. Cliquer sur ce type de lien nous renvoie directement sur la ressource dsigne sans aucune interprtation particulire du framework
JSF. Ce type de lien est intressant lorsque vous dsirez naviguer vers diffrents sites web.
Attributs Description
action
(<h:commandButton> et <h:commandLink> uniquement)
Si vous proposez une chane de caractres cet attribut, c'est que vous dsignez la nouvelle page web atteindre instantanment lorsque
l'utilisateur clique sur un de ces composants.
Si vous spcifiez une mthode d'un bean au travers d'une expression EL, la mthode est alors excute lorsque l'utilisateur clique sur un
de ces composants. Si cette mthode renvoie une chane de caractres, elle doit alors correspondre l'identification de la nouvelle page
atteindre.
Si vous n'utilisez pas cet attribut, c'est la page web en cours qui est raffiche lorsque l'utilisateur clique sur un de ces composants.
outcome (<h:button> et <h:link> uniquement) indique la prochaine cible atteindre lorsque le composant s'affichera.
fragment (<h:button> et <h:link> uniquement) Un fragment qui se rajoute l'URL cible. Le sparateur # est automatiquement appliqu et vous
n'avez pas besoin de l'inclure dans votre fragment.
actionListener Prise en compte d'un vnement de type action et lance la mthode du bean propose - mthode(ActionEvent)
image (<h:commandButton> et <h:button> uniquement) L'image propose s'affiche la place du rendu classique d'un bouton.
immediate La valeur attendue est de type boolen. La valeur par dfaut est false. Dans ce cas l, les actions et les vnements sont pris en compte
uniquement la fin du cycle de vie, c'est--dire aprs les phases de conversion et de validation. Si par contre, vous proposez la valeur
true, les actions et les vnements sont pris en compte immdiatement.
type Pour <h:commandButton> les types prvus sont : button, submit et reset. Par dfaut, sauf si vous spcifiez l'attribut image, est submit.
Pour <h:commandLink> et <h:link> : correspond au type MIME (type de ressource), text/html, image/gif ou audio/basic par exemple.
value Intitul du bouton ou du lien. Cela peut tre une chane de caractres ou une expression EL.
Les slections
Les composants de slection permettent de choisir une ou plusieurs valeurs dans une liste. Graphiquement, ils sont reprsents par des cases cocher, des
boutons radio, des listes ou des combos box.
Balises Description
<h:selectBooleanCheckbox> Gnre une case cocher reprsentant une valeur boolenne unique. Cette cas sera initailement coche ou dcoche selon
la valeur de sa proprit checked.
<h:selectManyCheckbox> Gnre une liste de cases cocher.
<h:selectManyListBox> Gnre un composant choix multiples, dans lequel nous pouvons choisir une ou plusieurs options.
<h:selectManyMenu> Gnre une balise <select> HTML.
<h:selectOneListBox>
Gnre un composant choix unique, dans lequel nous ne pouvons choisir qu'une seule option.
<h:selectOneMenu> Gnre un composant choix unique, dans lequel nous ne pouvons choisir qu'une seule option. N'affiche qu'une option
la fois.
<h:selectOneRadio> Gnre une liste de boutons radio.
Les marqueurs de ce tableau ont une reprsentation garphique, mais ils ont besoin d'imbriquer d'autres marqueurs (<f:selectItem> ou <f:selectItems>)
pour obtenir l'ensemble des valeurs disponibles.
<h:selectOneMenu value="#{test.semaine}">
<f:selectItem itemValue="Lundi" />
<f:selectItem itemValue="Mardi" />
<f:selectItem itemValue="Mercredi" />
<f:selectItem itemValue="Jeudi" />
<f:selectItem itemValue="Vendredi" />
<f:selectItem itemValue="Samedi" />
<f:selectItem itemValue="Dimanche" />
</h:selectOneMenu>
Attributs Description
enabledClass,
disabledClass
(<h:selectOneRadio> et <h:selectManyCheckbox> uniquement) Possibilit de placer des styles CSS sur la prise en compte ou pas
de cet lment.
selectedClass,
unselectedClass
(<h:selectManyCheckbox> uniquement) Possibilit de placer des styles CSS sur la prise en compte de la slection ou pas de cet
lment.
layout (<h:selectOneRadio> et <h:selectManyCheckbox> uniquement) Spcification qui dtermine l'orientation de l'ensemble des cases
cocher ou des boutons radio lineDirection (horizontal) ou pageDirection (vertical)
label Description du composant utilisable lors d'un message d'erreur.
collectionType (<h:selectMany...> uniquement) Une chane de caractres ou une expression EL qui identifie une collection.
hideNoSelectionOption Cache tous les lments qui sont dsigns comme "aucune slection" noSelectionOption dans les balise <f:selectItem>.
<h:selectBooleanCheckbox value="#{test.validation}" id="validation">
<h:outputLabel value="Contactez-moi " for="validation" />
</h:selectBooleanCheckbox>
@ManagedBean
public class Test {
private boolean validation;
public boolean isValidation() {
return validation;
}
public void setValidation(boolean validation) {
this.validation = validation;
}
}
Cette balise reprsente une seule case cocher qui doit tre
rattache une proprit boolenne.
<h:selectManyCheckbox value="#{test.couleurs}">
<f:selectItem itemLabel="Rouge" itemValue="Color.RED"/>
<f:selectItem itemLabel="Jaune" itemValue="Color.YELLOW" />
<f:selectItem itemLabel="Bleu" itemValue="Color.BLUE" />
<f:selectItem itemLabel="Vert" itemValue="Color.GREEN" />
<f:selectItem itemLabel="Orange" itemValue="Color.ORANGE" />
</h:selectManyCheckbox>
<hr />
<h:commandButton value="Choisissez vos couleurs" />
<hr />
<h:dataTable value="#{test.couleurs}" var="couleur">
<h:column>#{couleur}</h:column>
</h:dataTable>
<hr />
@ManagedBean
public class Test {
private ArrayList<Color> couleurs = new ArrayList<Color>();
public ArrayList<Color> getCouleurs() {
return couleurs;
}
public void setCouleurs(ArrayList<Color> couleurs) {
Vous avez la possibilit de regrouper un ensemble de cases
cocher l'aide de cette balise. Cela implique qu'il est possible
de slectionner plusieurs lments, et la valeur de la proprit
doit correspondre une collection.
La balise <f:selectItem> possde deux attributs. Le premier,
itemValue reprsente la valeur de l'lment. Le deuxime,
itemLabel reprsente l'intitul. Vous ne l'utilisez que dans le
cas o ce dernier est diffrent de la valeur.
this.couleurs = couleurs;
}
}
cas o ce dernier est diffrent de la valeur.
<h:panelGrid columns="2" border="1" cellspacing="0">
<h:panelGroup>
<h:selectManyCheckbox value="#{test.couleurs}" layout="pageDirection" >
<f:selectItem itemLabel="Rouge" itemValue="Color.RED"/>
<f:selectItem itemLabel="Jaune" itemValue="Color.YELLOW" />
<f:selectItem itemLabel="Bleu" itemValue="Color.BLUE" />
<f:selectItem itemLabel="Vert" itemValue="Color.GREEN" />
<f:selectItem itemLabel="Orange" itemValue="Color.ORANGE" />
</h:selectManyCheckbox>
</h:panelGroup>
<h:panelGroup>
<h:commandButton value="Choisissez vos couleurs" />
<hr />
<h:dataTable value="#{test.couleurs}" var="couleur">
<h:column>#{couleur}</h:column>
</h:dataTable>
</h:panelGroup>
</h:panelGrid>
Il est possible de choisir l'orientation des cases cocher (pour
les boutons radio aussi). Par dfaut, c'est un alignement
horizontal qui est propos. Vous pouvez choisir l'alignement
vertical en spcifiant la valeur pageDirection dans l'attribut
layout.
<h:panelGrid columns="2" border="1" cellspacing="0">
<h:panelGroup>
<h:selectOneRadio value="#{test.couleur}" layout="pageDirection" >
<f:selectItem itemLabel="Rouge" itemValue="#FF0000"/>
<f:selectItem itemLabel="Jaune" itemValue="#FFFF00" />
<f:selectItem itemLabel="Bleu" itemValue="#0000FF" />
<f:selectItem itemLabel="Vert" itemValue="#00FF00" />
<f:selectItem itemLabel="Orange" itemValue="#FF6600" />
</h:selectOneRadio>
</h:panelGroup>
<h:panelGroup>
<h:commandButton value="Choisissez votre couleur" />
<hr />
Choix : <br />
<h:inputTextarea value="#{test.couleur}" readonly="true"
style="background: #{test.couleur}"/>
</h:panelGroup>
</h:panelGrid>
@ManagedBean
public class Test {
private String couleur = "#FFFF00";
public String getCouleur() {
return couleur;
}
public void setCouleur(String couleur) {
this.couleur = couleur;
}
}
Il est galement possible de faire un choix parmi plusieurs
valeurs proposes, ce qui correspond au boutons radios.
Cette fois-ci la valeur de la proprit doit reprsenter un
lment unique.
<h:panelGrid columns="2" border="1" cellspacing="0">
<h:panelGroup>
<h:selectOneListbox value="#{test.couleur}" >
<f:selectItem itemLabel="Rouge" itemValue="#FF0000"/>
<f:selectItem itemLabel="Jaune" itemValue="#FFFF00" />
<f:selectItem itemLabel="Bleu" itemValue="#0000FF" />
<f:selectItem itemLabel="Vert" itemValue="#00FF00" />
<f:selectItem itemLabel="Orange" itemValue="#FF6600" />
</h:selectOneListbox>
</h:panelGroup>
<h:panelGroup>
<h:commandButton value="Choisissez votre couleur" />
<hr />
<h:inputText value="#{test.couleur}" readonly="true"
style="background: #{test.couleur}" size="23"/>
</h:panelGroup>
</h:panelGrid>
Une autre solution pour faire un choix parmi plusieurs valeurs
proposes, c'est d'utiliser une liste. L aussi, la valeur de la
proprit doit reprsenter un lment unique.
Par dfaut, tous les lments de la liste sont systmatiquement
visibles. Vous avez la possibilt de limiter le nombre
d'lments visibles au moyen de l'attribut size. Un ascenceur
vertical sera alors propos.
<h:panelGrid columns="2" border="1" cellspacing="0">
<h:panelGroup>
<h:selectManyListbox value="#{test.couleurs}" layout="pageDirection" >
<f:selectItem itemLabel="Rouge" itemValue="Color.RED"/>
<f:selectItem itemLabel="Jaune" itemValue="Color.YELLOW" />
<f:selectItem itemLabel="Bleu" itemValue="Color.BLUE" />
<f:selectItem itemLabel="Vert" itemValue="Color.GREEN" />
<f:selectItem itemLabel="Orange" itemValue="Color.ORANGE" />
</h:selectManyListbox>
</h:panelGroup>
<h:panelGroup>
<h:commandButton value="Choisissez vos couleurs" />
<hr />
<h:dataTable value="#{test.couleurs}" var="couleur">
Grce cette balise, vous pouvez aussi prendre en compte
plusieurs valeurs dans une liste. Attention, il faut que la
proprit qui gre l'ensemble des valeurs choisies soit une
collection.
<h:column>#{couleur}</h:column>
</h:dataTable>
</h:panelGroup>
</h:panelGrid>
@ManagedBean
public class Test {
private ArrayList<Color> couleurs = new ArrayList<Color>();
public ArrayList<Color> getCouleurs() {
return couleurs;
}
public void setCouleurs(ArrayList<Color> couleurs) {
this.couleurs = couleurs;
}
}
<h:panelGrid columns="2" border="1" cellspacing="0">
<h:panelGroup>
<h:selectOneMenu value="#{test.couleur}" >
<f:selectItem itemLabel="Rouge" itemValue="#FF0000"/>
<f:selectItem itemLabel="Jaune" itemValue="#FFFF00" />
<f:selectItem itemLabel="Bleu" itemValue="#0000FF" />
<f:selectItem itemLabel="Vert" itemValue="#00FF00" />
<f:selectItem itemLabel="Orange" itemValue="#FF6600" />
</h:selectOneMenu>
</h:panelGroup>
<h:panelGroup>
<h:commandButton value="Choisissez votre couleur" />
<hr />
<h:inputText value="#{test.couleur}" readonly="true"
style="background: #{test.couleur}" size="23"/>
</h:panelGroup>
</h:panelGrid>
Une dernire solution pour faire un choix parmi plusieurs
lments est la liste droulante, souvent appel menu dans les
applications web.
La balise <f:selectItem>
Dans tous les exemples que nous venons de voir, la balise <f:selectItem> reprsente un seul lment de l'ensemble de la slection. Pour connatre tous les
choix possibles, vous devez donc proposer un ensemble de balise <f:selectItem> imbriqus l'intrieur du type de rprsentation que vous dsirez obtenir.
Dans l'exemple ci-dessus, une des valeurs : #FF0000, #FFFF00, #0000FF, etc. va tre transmise la proprit couleur du bean test, lorsque le choix est
effectu et lorsque l'ordre de soumission a t envoy.
L'attribut itemValue reprsente une de ces valeurs. Si cette valeur est celle que vous dsirez visualiser dans le rendu de la page web, vous n'avez pas
besoin d'autre attribut. Si par contre, vous souhaitez proposer un intitul diffrent de la valeur envoyer, vous pouvez alors utiliser l'attribut
itemLabel.
Avec la valeur et son tiquette, dans un lment de slection, vous pouvez aussi lui proposer une description ou mme le dsigner temporairement
inactif. Par ailleurs, avec JSF 2.0, il existe un attribut supplmentaire noSelectionOption qui permet de dsigner l'lment comme une invitation
choisir une slection et non comme une valeur prendre en compte. Cet attribut s'utilise en conjonction avec la phase de validation. Dans le cas d'un
non choix de la par de l'utilisateur, un message d'erreur peut alors tre propos.
<h:panelGrid columns="1" style="background: darkgreen" cellpadding="3">
<h:panelGroup>
<h:selectOneMenu value="#{test.couleur}" id="choix" required="true"
requiredMessage="Faites votre choix !">
<f:selectItem itemLabel="Choisissez votre couleur" noSelectionOption="true" />
<f:selectItem itemLabel="Rouge" itemValue="#FF0000" itemDisabled="true"/>
<f:selectItem itemLabel="Jaune" itemValue="#FFFF00" />
<f:selectItem itemLabel="Bleu" itemValue="#0000FF" />
<f:selectItem itemLabel="Vert" itemValue="#00FF00" />
<f:selectItem itemLabel="Orange" itemValue="#FF6600" />
</h:selectOneMenu>
<h:commandButton value="Ok" />
</h:panelGroup>
<h:message for="choix" />
<h:inputText value="#{test.couleur}" readonly="true"
style="background: #{test.couleur}" size="30" />
</h:panelGrid>
Attributs Description
itemDescription
Description de l'lment utile uniquement avec un outil adapt.
itemDisabled Permet de rendre temporairement un lment inactif.
itemLabel Texte envoy pour le rendu de l'lment (partie visuelle).
itemValue Valeur prise en compte par la requte soumise au serveur d'applications.
escape Permet d'intgrer des caractres spciaux qui ne doivent pas tre interprter par JSF.
value Expression EL qui identifie un objet de type SelectItem.
<f:selectItem value="#{test.couleurRouge}" />
SelectItem getCouleurRouge() { return new SelectItem("Rouge", "#FF0000"); }
// Constructeurs possibles
SelectItem(Object value)
SelectItem(Object value, String label)
SelectItem(Object value, String label, String description)
SelectItem(Object value, String label, String description, boolean disabled)
SelectItem(Object value, String label, String description, boolean disabled, boolean escape)
SelectItem(Object value, String label, String description, boolean disabled, boolean escape, boolean noSelectionOption)
noSelectionOption Proposer la valeur true si cet lment n'est pas un choix possible dans la liste de slection.
La balise <f:selectItems>
La balise <f:selectItem> est polyvalente, mais cela peut s'avrer rapidement fastidieux d'crire systmatiquement l'ensemble des choix possibles sur la vue.
Nous pouvons rduire considrablement le code en proposant plutt la balise <f:selectItems>. Dans ce cas, c'est le modle qui doit prendre le relais et se
proccuper de spcifier l'ensemble des lments que comporte la slection.
La vue
<h:body style="background-color: green; color: yellow; font-weight: bold">
<h:form>
<h:panelGrid columns="1" style="background: darkgreen" cellpadding="3">
<h:panelGroup>
<h:selectOneMenu value="#{test.couleur}" id="choix" required="true" requiredMessage="Faites votre choix !">
<f:selectItems value="#{test.couleurs}" />
</h:selectOneMenu>
<h:commandButton value="Ok" />
</h:panelGroup>
<h:message for="choix" />
<h:inputText value="#{test.couleur}" readonly="true" style="background: #{test.couleur}" size="30" />
</h:panelGrid>
</h:form>
</h:body>
Le modle
import javax.faces.bean.*;
import javax.faces.model.SelectItem;
@ManagedBean
public class Test {
private String couleur;
private SelectItem[] couleurs = {
new SelectItem(null, "Choisissez votre couleur", "", false, false, true),
new SelectItem("#FF0000", "Rouge", "", true),
new SelectItem("#FFFF00", "Jaune"),
new SelectItem("#0000FF", "Bleu"),
new SelectItem("#00FF00", "Vert"),
new SelectItem("#FF6600", "Orange")
};
public String getCouleur() { return couleur; }
public void setCouleur(String couleur) { this.couleur = couleur; }
public SelectItem[] getCouleurs() { return couleurs; }
}
L'attribut value de la balise <f:selectItems> doit possder une expression EL qui reprsente l'un des quatre points suivants : une instance d'un seul
SelectItem, une collection, un tableau ou une carte o chaque entre reprsente une tiquette suivie de sa valeur.
Une balise <f:selectitems> est trs souvent plus facile manipuler que la balise <f:selectItem>. Dans le cas o le nombre d'lments varie, avec
<f:selectItems>, gnralement vous avez besoin de changer uniquement que le modle, alors qu'avec la balise <f:selectItem>, vous devez modifier la
fois la vue et le modle.
Attributs Description
value Expression EL qui reprsente un seul lment, une collection, un tableau ou une carte d'entres.
var Nom de la variable qui va tre utilise pour rcuprer les proprits d'un lment de la collection pour renseigner en une seule fois
son intitul et sa valeur, respectivement exprims au travers des attributs itemLabel et itemValue.
itemLabel Intitul de l'lment associ l'attribut var.
itemValue Valeur de l'lment associ l'attribut var.
itemDescription Description de l'lment associ l'attribut var.
itemDisabled Rendre l'lment associ l'attribut var momentanment inactif.
itemLabelEscape Permettre l'lment associ l'attribut var de ne pas interprter le code interne.
noSelectionOption Elment associ l'attribut var qui ne fait pas parti de la slection.
Avant JSF 2.0, les collections et les tableaux devaient contenir imprativement des instances de type SelectItem, comme l'exemple propos plus haut.
Nous remarquons tout de suite que l aussi cela peut tre assez fastidieux. Depuis lors, il est maintenant possible de proposer une collection ou un
tableau de n'importe quel type d'objets, ce qui est largement plus intressant.
Si vous utilisez une classe quelconque comme lment de votre collection, les intituls de vos slections sont gnrs automatiquement partir de la
mthode toString() de votre classe. A vous de redfinir cette mthode pour que tout se fasse automatiquement.
<h:selectOneMenu value="#{test.jour}">
<f:selectItems value="#{test.jours}" />
</h:selectOneMenu>
@ManagedBean
public class Test {
private enum JourSemaine {Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche};
private JourSemaine[] jours = JourSemaine.values();
private JourSemaine jour;
public JourSemaine[] getJours() { return jours; }
public JourSemaine getJour() { return jour; }
public void setJour(JourSemaine jour) { this.jour = jour; }
}
D'une autre faon, vous pouvez utiliser l'attribut var pour dfinir une variable qui reprsente chaque lment particulier de la collection. Nous pouvons
faire correspondre cette variable, l'intitul ainsi que la valeur associe, en prenant en compte les proprits lies l'lment, en spcifiant ainsi les
attributs itemLabel et itemValue.
Dans le mme ordre d'ide, vous pouvez dfinir l'lment qui portera une description, qui sera momentanment inactif ou qui ne fera pas parti de la
slection au moyen des attributs respectifs : itemDescription, itemDisabled et noSelectionOption.
<style type="text/css">
body { background-color: green; color: yellow; }
.fond, .droite { background: yellow; font-weight: bold; }
.droite { text-align: right; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" style="background: darkgreen" cellpadding="3">
<h:selectOneMenu value="#{test.nombreJours}" onchange="submit()" styleClass="fond">
<f:selectItems value="#{test.mois}" var="mois" itemValue="#{mois.numroMois}" />
</h:selectOneMenu>
<h:inputText value="#{test.nombreJours}" readonly="true" size="3" styleClass="droite"/>
</h:panelGrid>
</h:form>
</h:body>
@ManagedBean
public class Test {
public enum Mois {
Janvier, Fvrier, Mars, Avril, Mai, Juin, Juillet, Aot,
Septembre, Octobre, Novembre, Dcembre;

public int getNumroMois() { return ordinal()+1; }
};

private Mois[] mois = Mois.values();
private int nombreJours;
public Mois[] getMois() { return mois; }

public int getNombreJours() { return nombreJours; }
public void setNombreJours(int nombreJours) {
this.nombreJours = nombreJours;
}
}
Liaison entre l'attribut value et la proprit du bean gr
Lorsque vous utilisez un ensemble de cases cocher, des menus ou des listes, vous avez toujours besoin de rcuprer l'lment slectionn par rapport
l'ensemble propos. Comme nous venons de le voir, vous devez alors utiliser l'attribut value associe une proprit du bean gr au travers d'une
expression EL. Cette proprit correspond ainsi la valeur dlivre par l'attribut itemValue de l'lment.
ATTENTION, lorsque la requte est soumise, le serveur d'application reoit la chane slectionne (protocole HTTP) et doit le convertir dans le type
appropri. L'implmentation JSF sait comment convertir un nombre ou une numration, mais vous tes oblig de prvoir un convertisseur dans tous
les autres cas.
Les messages d'erreur
Les beans grs traitent de la logique mtier, appellent les EJB, utilisent les bases de donnes, etc. Parfois, cependant, un problme peut survenir et, en ce
cas, l'utilisateur doit tre inform par un message qui peut tre un message d'erreur de l'application (concernant la logique mtier ou la connexion la base
ou au rseau) ou un message d'erreur de saisie (un ISBN incorrect ou un champ vide par exemple).
Les erreurs d'application peuvent produire une page particulire demandant l'utilisateur de ressayer dans un moment, par exemple, alors que les
erreurs de saisie peuvent s'afficher dans la mme page avec un texte dcrivant l'erreur. Nous pouvons galement utiliser des messages pour informer
l'utilisateur qu'un livre a t correctement ajout la base de donnes.
Typiquement, pour les erreurs de saisie, les messages sont associs avec un composant particulier et prcise qu'une erreur de conversion ou de
validation est survenue. Bien que nous utilisons les messages souvent de la mme faon, il existe en ralit quatre varits de message : Information,
Avertissement, Erreur et Fatal.
Tous les types de message comporte une description sommaire et une description dtaille. Par exemple, de faon sommaire nous pourrions dire que
l'entre est invalide, alors que dans le dtail nous pourrions indiquer que le nombre saisi est plus grand que la valeur maximal prvue. Les
applications JSF utilise deux balises pour reprsenter ces messages : <h:messages> et <h:message>.
1. <h:messages> : Cette balise affiche tous les messages d'erreur survenant dans l'ensemble de la page.
2. <h:message> : Cette balise affiche un seul message d'erreur associ un composant en particlier. Ce composant est spcifi au travers de l'attribut
for, lui-mme devra proposer un identifiant.
Attributs Description
Attributs Description
errorClass, errorStyle, fatalClass,
fatalStyle, infoClass, infoStyle,
warnClass, warnStyle
Styles CSS associs aux quatre types de message d'erreur.
for Identifiant dsignant le composant prendre en compte pour afficher un ventuel message d'erreur le
concernant. (<h:message> uniquement).
globalOnly Instruction imposant d'afficher uniquement les messages d'erreur globaux, les messages particuliers tant alors
dsactivs. (<h:messages> uniquement).
layout Permet de spcifier l'orientation de l'ensemble des messages d'erreur survenant : "table" ou "list". (<h:messages>
uniquement).
showDetail Boolen qui dtermine si le message d'erreur doit tre affich sous forme dtaill. Par dfaut, les valeurs sont
false pour <h:messages> et true pour <h:message>.
showSummary Boolen qui dtermine si le message d'erreur doit tre affich sous forme simplifie. Par dfaut, les valeurs sont
true pour <h:messages> et false pour <h:message>.
tooltip Boolen qui dtermine si un message dtaill doit tre rendu visible dans une petite bulle d'avertissement. Cet
avertissement ne sera toutefois visible uniquement la condition que les attributs showDetail et showSummary
soient valids.

<style type="text/css">
body { background-color: green; color: yellow; font-weight: bold; }
.cadre { background: darkgreen; }
.erreur { color: chartreuse; font-style: italic; text-align: left; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="3" styleClass="cadre">
<f:facet name="header">
<h:messages styleClass="erreur"/>
</f:facet>
Nom :
<h:inputText id="nom" value="#{test.nom}" required="true" label="Nom"/>
<h:message for="nom" errorClass="erreur" />
ge :
<h:inputText id="ge" value="#{test.ge}" size="3" label="ge" />
<h:message for="ge" errorClass="erreur" />
<f:facet name="footer">
<hr />
<h:commandButton value="Soumettre" />
</f:facet>
</h:panelGrid>
</h:form>
</h:body>
Les messages d'erreurs proposes sont automatiquement traduite dans la langue locale. Ils sont relativement adapts la situation. Il est galement
possible de proposer un message personnalis sur chaque balise de saisie au moyen des attributs converterMessage, validatorMessage et
requiredMessage.

<style type="text/css">
body { background-color: green; color: yellow; font-weight: bold; }
.cadre { background: darkgreen; }
.erreur { color: chartreuse; font-style: italic; text-align: left; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="3" styleClass="cadre">
Nom :
<h:inputText id="nom" value="#{test.nom}" required="true" requiredMessage="Erreur : indispensable" />
<h:message for="nom" errorClass="erreur" />
ge :
<h:inputText id="ge" value="#{test.ge}" size="3" converterMessage="Erreur : valeur entre 0 et 120" />
<h:message for="ge" errorClass="erreur" />
<f:facet name="footer">
<hr />
<h:commandButton value="Soumettre" />
</f:facet>
</h:panelGrid>
</h:form>
</h:form>
</h:body>

Les donnes sous forme de tableau dynamique
Les donnes doivent souvent tre affiches sous forme de tableau. JSF fournit donc le marqueur <h:dataTable> permettant ainsi de parcourir une liste d'lments (dont
la taille est variable) afin de gnrer automatiquement un tableau. Typiquement, un tableau dynamique de donnes possde la structure suivante :
<h:dataTable value="#{lments}" var="lment">
<h:column>
#{lment.premireProprit}
</h:column>
<h:column>
#{lment.deuximeProprit}
</h:column>
...
</h:dataTable>
L'attribut value reprsente l'ensemble des donnes que pourra parcourir par itration la balise <h:dataTable>. Les donnes que peut exploiter l'attribut value est
de l'une des natures suivantes : un simple objet Java, un tableau, une instance de java.util.List, une instance de java.sql.ResultSet, une instance de
javax.faces.model.DataModel.
1. La balise <h:dataTable> prend en compte l'ensemble des lments constituant la collection choisie. Du coup, la longueur du tableau est totalement variable et
dpend du contenu en cours de la collection. Il s'agit donc bien d'un tableau dynamique qui affiche les donnes actuellement accessibles.
2. Chaque lment de la collection est reprsent par une ligne de la table. Il est possible d'identifier l'lment de la ligne courante en spcifiant l'attribut var de
la balise <h:dataTable>. Cet lment reprsente gnralement un simple objet avec lequel nous pouvons ensuite manipuler chaque proprit sparment,
reprsente dans une colonne distincte.
3. Plus rarement, au lien de proposer une collection, nous pouvons spcifier un seul objet Java dans l'attribut value de <h:dataTable>, auquel cas une seule ligne
apparatra puiqu'il n'existe qu'une seule occurrence.
4. Le corps de la balise <h:dataTable> ne peut contenir uniquement que des balises <h:column>. La balise <h:dataTable> ignore toutes les autres balises que
vous placerez. Par contre, chaque colonne peut contenir un nombre indfini de composants internes.
La balise <h:dataTable> est en relation avec un composant de type UIData qui s'occupe du rendu de la table. Cette combinaison permet de gnrer des tables
robustes qui supportent les styles CSS, l'accs aux bases de donnes, la personnalisation des modles de table, et bien d'autres. Nous allons commencer notre
exploration de ce marqueur <h:dataTable> en laborant tout d'abord une simple table.
<style>
body { background-color: green; color: yellow; font-weight: bold; }
.cadre { background: darkgreen; border-radius: 5px; padding: 7px;
box-shadow: -1px -1px 3px lightgreen, 1px 1px 2px black; }
.saisie { background: yellow; color: darkgreen; text-align: right;
padding-right: 5px; font-weight: bold; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" styleClass="cadre">
<h:outputText value="Prnom : " />
<h:inputText value="#{gestion.personne.prnom}" styleClass="saisie"/>
<h:outputText value="Nom : " />
<h:inputText value="#{gestion.personne.nom}" styleClass="saisie" />
<f:facet name="footer">
<hr />
<h:commandButton value="Nouveau" action="#{gestion.nouveau()}"/>
<h:commandButton value="Enregistrer" action="#{gestion.ajout()}" />
</f:facet>
</h:panelGrid>
<br />
<h:dataTable value="#{gestion.personnes}" var="personne"
styleClass="cadre" rendered="#{gestion.pasVide}">
<h:column>#{personne.prnom}</h:column>
<h:column>#{personne.nom}</h:column>
</h:dataTable>
</h:form>
</h:body>
@ManagedBean
@SessionScoped
public class Gestion {
private Personne personne = new Personne();
private ArrayList<Personne> personnes = new ArrayList<Personne>();
public Personne getPersonne() { return personne; }
public void setPersonne(Personne personne) { this.personne = personne; }
public ArrayList<Personne> getPersonnes() { return personnes; }

public void ajout() { personnes.add(personne); }
public void nouveau() { personne = new Personne(); }
public boolean isPasVide() { return !personnes.isEmpty(); }
}
public class Personne {
private String nom;
private String prnom;
public String getNom() { return nom; }
public String getPrnom() { return prnom; }

public void setNom(String nom) {
this.nom = nom.toUpperCase();
}
public void setPrnom(String prnom) {
if (prnom.isEmpty()) return;
StringBuilder chaine = new StringBuilder(prnom.toLowerCase());
chaine.setCharAt(0, Character.toUpperCase(chaine.charAt(0)));
this.prnom = chaine.toString();
}
}
Dans l'exemple ci-dessus, le bean gr gestion permet de grer l'ensemble des personnes enregistrer et possde donc une collection personnes qui
est donc rattache l'attribut value de la balise <h:dataTable>. Ensuite, grce l'attribut var de cette balise, nous pouvons visulaiser chaque personne
en particulier sur chacune des lignes du tableau. A l'intrieur de ce tableau, nous rajoutons deux balises <h:column> qui vont nous permettre de
visualiser ainsi sparment, sous formes de colonnes, le nom et le prnom de chaque personne.
Attributs Description des attributs de la balise <h:dataTable>
bgcolor Couleur de fond de la table.
border Largeur de la bordure de la table.
captionClass Style CSS associ au titre de la table.
cellpadding Espacement minimum l'intrieur de chaque cellule.
cellspacing Espacement entre les cellules.
columnClasses Liste des styles CSS pour les colonnes de la table.
dir Direction du texte : LTR (Left to Right) ou RTL (Right to Left).
first Index de la collection partir duquel nous commenons afficher la premire ligne du tableau.
footerClass Style CSS associ au pied du tableau.
frame Spcification pour dterminer le comportement du cadre par rapport son environnement. Valeurs attendues : none, above, below,
hsides, vsides, lhs, rhs, box, border.
headerClass Style CSS pour spcialement prvue pour la partie en-tte.
rowClasses Liste des styles CSS pour les lignes de la table.
rows Nombre de lignes affichable dans la table. Gnralement en relation avec l'attribut first. Si vous proposez la valeur 0, toute les lignes de la
table vont tre affiches.
rules Rgles spcifique aux tracs des lignes entre les cellules. Valeurs possibles : groups, rows, columns, all.
summary Sommaire de la table non visible, pour une utilisation en coulisse.
var Nom propos qui reprsente la ligne courante, une valeur spcifique de l'ensemble de la collection.
Attributs Description des attributs de la balise <h:columns>
footerClass Style CSS associ au pied du tableau.
headerClass Style CSS pour spcialement prvue pour la partie en-tte.
En-tte, pied et titre sur une table
Si nous affichons la liste des noms et prnoms comme nous venons de le faire dans le projet prcdent, ce n'est pas trs agable car il n'est par toujours
facile de s'y retrouver entre le nom et le prnom d'une personne. Il serait souhaitable de proposer au moins un titre chacune des colonnes visibles.
A l'image de la balise <h:panelGrid>, nous avons la possiblit de rajouter des facettes pour spcifier une partie en-tte, un pied sur chacune des
colonnes et un titre sur l'ensemble de la table.
<style>
body { background-color: green; color: yellow; font-weight: bold; }
.cadre { background: darkgreen; border-radius: 5px; padding: 7px;
box-shadow: -1px -1px 3px lightgreen, 2px 2px 5px black; }
.saisie { background: yellow; color: darkgreen; text-align: right; padding-right: 5px;
font-weight: bold; }
.en-tete { background: lightgreen; color: darkgreen; }
.colonne { padding: 4px; width: 124px; }
</style>
<h:body>
<h:form>
<h:panelGrid columns="2" styleClass="cadre" >
<h:outputText value="Prnom : " />
<h:inputText value="#{gestion.personne.prnom}" styleClass="saisie"/>
<h:outputText value="Nom : " />
<h:inputText value="#{gestion.personne.nom}" styleClass="saisie" />
<f:facet name="footer">
<hr />
<h:commandButton value="Nouveau" action="#{gestion.nouveau()}"/>
<h:commandButton value="Enregistrer" action="#{gestion.ajout()}" />
</f:facet>
</h:panelGrid>
<h:dataTable value="#{gestion.personnes}" var="personne" styleClass="cadre"
headerClass="en-tete" captionClass="cadre"
columnClasses="colonne, colonne" rules="all" >
<f:facet name="caption">Liste des personnes</f:facet>
<h:column>
<f:facet name="header">Prnom</f:facet>
#{personne.prnom}
</h:column>
<h:column>
<f:facet name="header">Nom</f:facet>
#{personne.nom}
#{personne.nom}
</h:column>
</h:dataTable>
</h:form>
</h:body>
Composants dans une table et mode d'dition
Jusqu' prsent, nous n'avons plac uniquement des composants pour afficher du texte. En ralit, vous pouvez introduire une trs grande varit de
composants graphiques, des zones de saisie, des boutons, des images, des menus, des cases cocher, des boutons radio, des listes, etc.
En prvoyant tous ces types de composant, il devient possible d'avoir des tables ditables, pour saisir de nouvelles entres, modifier celles qui sont
dj prsentes, supprimer des lignes, etc.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<style>
body { background-color: green; color: yellow; font-weight: bold; }
.cadre { background: darkgreen; border-radius: 5px; padding: 7px;
box-shadow: -1px -1px 3px lightgreen, 2px 2px 5px black; }
input[type="text"] { background: yellow; color: darkgreen; font-weight: bold; }
.en-tete { background: green; padding-left: 10px; padding-right: 10px;
border-radius: 3px; text-shadow: 2px 2px 7px black; }
</style>
<h:body>
<h:form>
<h:dataTable value="#{gestion.personnes}" var="personne" styleClass="cadre" columnClasses="en-tete">
<h:column headerClass="en-tete">
<f:facet name="header">Mari</f:facet>
<h:selectBooleanCheckbox value="#{personne.mari}" />
</h:column>
<h:column headerClass="en-tete">
<f:facet name="header">Prnom</f:facet>
<h:inputText value="#{personne.prnom}" />
</h:column>
<h:column headerClass="en-tete">
<f:facet name="header">Nom</f:facet>
<h:inputText value="#{personne.nom}" />
</h:column>
<h:column><h:commandButton value="Enregistrer" /></h:column>
<h:column>
<h:commandButton value="Supprimer" action="#{gestion.supprimer(personne)}" />
</h:column>
<f:facet name="footer">
<hr />
<h:commandButton value="Ajouter" action="#{gestion.ajout()}" />
</f:facet>
</h:dataTable>
</h:form>
</h:body>
</html>
@ManagedBean
@SessionScoped
public class Gestion {
private ArrayList<Personne> personnes = new ArrayList<Personne>();
public ArrayList<Personne> getPersonnes() { return personnes; }

@PostConstruct
public void ajout() { personnes.add(new Personne()); }

public void supprimer(Personne personne) {
personnes.remove(personne);
if (personnes.isEmpty()) personnes.add(new Personne());
}
}
Dans cet exemple, nous avons placs des composants diffrents dans l'ensemble des colonnes, des cases cocher, des zones de saisie et pour finir des
boutons de commande.
Vous remarquez qu'il est mme possible de supprimer une ligne. Il suffit de faire appel la mthode qui permet cette suppression en passant en
paramtre l'objet correspondant la ligne courante, celui qui est donc dclar par l'attribut var de la balise <h:dataTable>. Pour ajouter une nouvelle
ligne, il suffit de rajouter un nouvel objet vierge votre collection et de rafrachir la page, et le tour est jou.

Projet de conclusion
Pour conclure cette premire partie sur JSF, je vous propose de mettre en oeuvre un dernier projet qui valide les diffrents concepts que nous venons de dcouvrir. La
prochaine tude nous permettra d'aller un peu plus loin dans le domaine. Nous verrons notamment comment :
1. Raliser des modles de page,
2. Crer de nouveau composants,
3. Construire des convertisseurs et des validateurs personnaliss,
4. S'occuper de toute la partie vnementielle,
5. Intgrer des modules sous Ajax,
6. etc.
Le projet que je vous propose permet de raliser une srie de conversions montaires. L'ensemble des conversions sont systmatiquement enregistres dans une
base de donnes. Elles sont accessibles dans un tableau limit quatre conversions visibles en mme temps. Vous pouvez par contre naviguer dans l'ensemble
des pages.
Voici maintenant l'ensemble des lments qui constitue le projet, respectivement :
1. L'entit Conversion qui rend persistant l'ensemble des conversions,
2. Le bean gr CDI Grer qui est galement un bean session qui sert de modle pour l'application web et qui s'occupe de la persistance de l'entit
Conversion.
3. La feuille de style principal.css utile pour la vue,
4. La page unique du site index.xhtml qui sert de vue l'application web
L'entit entit.Conversion
package entit;
import java.io.Serializable;
import javax.persistence.*;
@Entity
@NamedQuery(name="toutesLesConversions", query="SELECT conversion FROM Conversion conversion")
public class Conversion implements Serializable {
@Id @GeneratedValue
private long id;
private double euro;
private double franc;
private char sens;
public long getId() { return id; }
public double getEuro() { return euro; }
public double getFranc() { return franc; }
public char getSens() { return sens; }
public void setSens(char sens) { this.sens = sens; }
public Conversion(char sens, double euro, double franc) {
this.sens = sens;
this.euro = euro;
this.franc = franc;
}

public Conversion() { }
}
Le bean session stateful et CDI bean.Grer
package bean;
import entit.Conversion;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.*;
@Named
@SessionScoped
@Stateful
public class Grer {
@PersistenceContext
private EntityManager bd;
private List<Conversion> conversions;
private final double TAUX = 6.55957;
private double euro;
private double franc;
private char sens = 'F';
private int pages;
private int page;
public double getEuro() { return euro; }
public void setEuro(double euro) { this.euro = euro; }
public double getFranc() { return franc; }
public void setFranc(double franc) { this.franc = franc; }
public char getSens() { return sens; }
public void setSens(char sens) { this.sens = sens; }

public List<Conversion> getConversions() { return conversions; }
public int getPages() { return pages; }
public int getPage() { return page; }

@PostConstruct
public void liste() {
Query requte = bd.createNamedQuery("toutesLesConversions");
conversions = requte.getResultList();
pages = ((conversions.size() - 1) / 4) + 1;
}

public void convertir() {
switch (sens) {
case '' : euro = franc / TAUX; break;
case 'F' : franc = euro * TAUX; break;
}
bd.persist(new Conversion(sens, euro, franc));
liste();
}

public void supprimer(Conversion conversion) {
bd.remove(bd.find(Conversion.class, conversion.getId()));
liste();
}

public void changerPage(int dcalage) {
page += dcalage;
}
}
La feuille de style web/css/principal.css
root {
display: block;
}
body {
background-color: green;
color: yellow;
font-weight: bold;
}
.cadre {
background: darkgreen;
border-radius: 5px;
padding: 7px;
box-shadow: -1px -1px 3px lightgreen, 2px 2px 5px black;
}
.saisie, .resultat, .pages {
background: yellow;
color: darkgreen;
font-weight: bold;
text-align: right;
padding-right: 7px;
padding-left: 7px;
}
.saisie {
margin-right: 15px;
margin-left: 15px;
}
.resultat, .pages {
border-radius: 5px;
box-shadow: 1px 1px 3px black inset;
margin-left: 20px;
}
.resultat {
width: 170px;
display: block;
}
.fond {
background: black;
padding: 6px;
border-radius: 5px;
opacity: 0.9;
}
La vue index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<h:head />

<h:outputStylesheet name="principal.css" library="css" />
<h:body>
<h:form>
<h:dataTable value="#{grer.conversions}"
var="conversion"
styleClass="cadre"
footerClass="fond"
headerClass="fond"
rows="4"
first="#{grer.page * 4}">

<f:facet name="header">
<h:inputText value="#{grer.euro}" styleClass="saisie">
<f:convertNumber type="currency" currencySymbol="Euros"/>
</h:inputText>
<h:selectOneMenu value="#{grer.sens}">
<f:selectItem itemLabel="en Euro" itemValue="" />
<f:selectItem itemLabel="en Franc" itemValue="F" />
</h:selectOneMenu>
<h:inputText value="#{grer.franc}" styleClass="saisie">
<f:convertNumber type="currency" currencySymbol="Francs"/>
</h:inputText>
<h:commandButton value="Convertir" action="#{grer.convertir()}" />
</f:facet>
<h:column headerClass="en-tete">
<h:outputText value="#{conversion.euro}" styleClass="resultat">
<f:convertNumber type="currency" currencySymbol="Euros" />
</h:outputText>
</h:column>
<h:column headerClass="en-tete">
<h:selectOneRadio value="#{conversion.sens}">
<f:selectItem itemLabel="" itemValue="" />
<f:selectItem itemLabel="F" itemValue="F" />
</h:selectOneRadio>
</h:column>
<h:column headerClass="en-tete">
<h:outputText value="#{conversion.franc}" styleClass="resultat">
<f:convertNumber type="currency" currencySymbol="Francs" />
</h:outputText>
</h:column>
<h:column>
</h:column>
<h:column>
<h:commandButton value="Supprimer" action="#{grer.supprimer(conversion)}" />
</h:column>
<f:facet name="footer">
<h:outputFormat value="{0} page{0, choice, 0#|2#s}" styleClass="pages">
<f:param value="#{grer.pages}" />
</h:outputFormat>
<h:commandButton value="Page prcdente" disabled="#{grer.page == 0}" action="#{grer.changerPage(-1)}"/>
<h:commandButton value="Page suivante" disabled="#{grer.page == grer.pages-1}" action="#{grer.changerPage(1)}" />
<h:outputFormat value="{0} page{0, choice, 0#|2#s}" styleClass="pages">
<f:param value="#{grer.pages}" />
</h:outputFormat>
</f:facet>
</h:dataTable>
</h:form>
</h:body>
</html>