Java pour le développement
d’applications Web : Java EE
JSF : Java Server Faces
Mickaël BARON - 2007
mailto:baron.mickael@gmail.com ou mailto:mickael.baron@serli.com
SERLI informatique
SERLI : www.serli.com
Société de services en informatique
Fondée en 1981
Située sur le site du Futuroscope, Poitiers
Réalisation de logiciels et assistance technique
Domaines de compétences
Systèmes d’informations
Embarqué et temps réel
Systèmes et réseaux
Gestion Electronique de Document (GED, PDM / PLM)
keulkeul.blogspot.com
Plateformes de développement (celles qui concernent les cours)
Plateforme Java : Java EE, Java SE, Eclipse
Plateforme Microsoft : C#, VB .NET
… JSF - M. Baron - Page 379
SERLI informatique
Equipes impliquées dans l’Open Source
Utilisation massive de briques Open Source
Formation / diffusion de cours concernant Java et l’Open Source
RMLL : 7ème rencontres mondiales du logiciel libre
Solutions Linux 2007 : Salon des Solutions Open Source pour
l’entreprise
Membre du consortium ObjectWeb
Gestion de projets Open Source
keulkeul.blogspot.com
JaasLounge : interopérabilité JAAS pour Java EE
JShaft : gestion de clusters Java EE
JWT Gen : tests fonctionnels automatisés
JSF - M. Baron - Page 380
Déroulement du cours JSF
Pédagogie du cours
Illustration avec de nombreux exemples
Des bulles d’aide tout au long du cours
Ceci est une alerte Ceci est une astuce
Pré-requis
Connaissance de Java
Connaissance des fondements du WEB (HTML, HTTP)
Connaissance des technologies « fondatrices » de Java EE (Servlet,
JSP, balises personnalisées)
Structuration du cours
keulkeul.blogspot.com
Démarrage par les bases de JSF (Bean et Navigation)
Pour chaque nouveau concept introduit, le présenter en détail
Terminer par des concepts plus complexes
Remerciements
Developpez.com [djo.mos pour ses commentaires]JSF - M. Baron - Page 381
Introduction : qu’est-ce-que c’est ...
Java Server Faces est un framework de développement
d’applications Web en Java permettant de respecter le
modèle d’architecture MVC et basé sur des composants côté
présentation
Java Server Faces permet
une séparation de la couche présentation des autres couches (MVC)
un mapping entre l’HTML et l’objet
un ensemble de composants riches et réutilisables
une liaison simple entre les actions côté client de l’utilisateur (event
keulkeul.blogspot.com
listener) et le code Java côté serveur
Création de nouveaux composants graphiques
JSF peut être utilisé pour générer autre chose que du HTML (XUL,
XML, WML, …) JSF - M. Baron - Page 382
Introduction : meilleur que Struts, les avantages …
Possibilité de créer de nouveaux composants
JSF permet de combiner plusieurs composants pour aboutir à un
composant plus complexe
Support différentes technologies d’affichage
JSF ne se limite pas à l’HTML (XUL, Flash, …)
Accès aux Beans par leurs noms en utilisant les Expressions
Language
Pour Struts nécessité de mémoriser le nom du formulaire
Simplification des définitions des contrôleurs et des Beans
keulkeul.blogspot.com
Simplification du fichier de configuration
L’orientation composants graphiques permet à JSF d’être
utilisé de manière plus simple dans les environnements de
développement (voir Sun Java Studio CreatorJSF 2)- M. Baron - Page 383
Introduction : meilleur que Struts … et les inconvénients
Maturité de Struts par rapport à JSF
Struts est largement utilisé en industrie alors que JSF est encore un
framework jeune
Confusion des noms
Avec Struts les noms des formulaires (form.jsp) et les contrôleurs
(form.do) avaient différentes URL’s
JSF utilisent les mêmes noms pour la vue et le contrôleur
La validation dans JSF n’est pas aussi fournie que Struts
Possibilité de générer du JavaScript avec Struts pas JSF
keulkeul.blogspot.com
Possibilité de vérifier la syntaxe d’une carte de crédit, utilisation
d’expressions régulières, …
Moins de documentation et de ressources
Nous allons tenter d’y remédier … JSF - M. Baron - Page 384
Introduction : une spec et plusieurs implémentations
JSF comme la plupart des technologies proposées par Sun est
définie dans une spécification JSR-127 (version 1.1) puis
JSR-252 (1.2)
Il existe donc plusieurs implémentations de JSF
Sun Reference : http://java.sun.com/javaee/javaserverfaces
Apache MyFaces : http://myfaces.apache.org
L’implémentation proposée par Apache est appelée MyFaces
Apache fournit des fonctionnalités additionnels via le sous
keulkeul.blogspot.com
projet : Tomahawk La version 1.1 est associé à
Composants graphiques J2EE 1.4 alors que la version 1.2
de JSF est associée à Java EE 5
Validators plus fournis JSF - M. Baron - Page 385
Introduction : documentations et ressources
Même si JSF n’est pas aussi utilisé et documenté que Struts,
de nombreux sites commencent à apparaître pour proposer
tutoriels et exemples (peu de ressource en français)
Tutoriels / Cours
Java EE training and tutorials : http://www.coreservlets.com
Tutoriaux chez Developpez.com : http://www.developpez.com
JM Doudoux : http://www.jmdoudoux.fr/accueil.htm
Site de référence : http://java.sun.com/javaee/javaserverfaces
Site du projet : http://javaserverfaces.dev.java.net
Tutorial Java EE : http://java.sun.com/javaee/5/docs/tutorial/doc
keulkeul.blogspot.com
FAQ : http://wiki.java.net/bin/view/Projects/JavaServerFacesSpecFaq
Exemples et composants
Exemples JSF (AJAX, composants) : http://jsftutorials.net
Communauté JSF : http://www.jsfcentral.com JSF - M. Baron - Page 386
Bibliothèque …
Pro JSF & Ajax : Building Rich Internet …
Auteur : Jonas Jacobi
Éditeur : Apress
Edition : 2006 - 464 pages - ISBN : 1-59059-580-7
JavaServer Faces in Action
Auteur : Kito Mann
Éditeur : Manning Publications
Edition : 2005 - 702 pages - ISBN : 1-93239-412-2
keulkeul.blogspot.com
Core JavaServer Faces
Auteur : David Geary and Cay Horstmann
Éditeur : Prentice Hall Ptr
Edition : 2004 - 658 pages - ISBN : 0-13146-305-5
JSF - M. Baron - Page 387
Introduction : comment ça marche …
L’interface utilisateur construite dans la page JSP est
générée à l’aide de la technologie JSF (résultat myUI)
Elle fonctionne sur le serveur et le rendu est retourné au
client
JSF s’appuie sur les technologies précédentes
Génération en Servlet
keulkeul.blogspot.com
Utilisation des composants JSF
dans les pages JSP
Les composants JSF sont exposés
aux JSPs grâce aux balises personnalisés JSF - M. Baron - Page 388
Introduction : principe pour traiter un formulaire
1. Construire le formulaire dans une page JSP en utilisant les
balises JSF
2. Développer un Bean qui effectue un « Mapping » avec les
valeurs du formulaire
3. Modifier le formulaire pour spécifier l’action et l’associer au
Bean
4. Fournir des Converters et des Validators pour traiter les
données du formulaire
5. Paramétrer le fichier faces-config.xml pour déclarer le Bean
et les règles de navigation
keulkeul.blogspot.com
6. Créer les pages JSP correspondant à chaque condition de
retour
7. Protéger les pages JSP utilisées par le contexte JSF de façon
à éviter d’y accéder directement JSF - M. Baron - Page 389
Plan du cours JSF
Configuration : utiliser JSF dans une application Java EE
Bean Managé : stocker, afficher les valeurs d’un formulaire
Cycle de vie : comprendre les rouages d’un composant JSF
Navigation : choisir une vue selon un message
Composants CORE et HTML : gérer et construire la vue
FacesContext : manipuler informations du contexte
BackingBean : manipuler les instances des composants
Message : stocker et afficher des messages dans les JSP
Converters : transformer les valeurs saisies d’un formulaire
keulkeul.blogspot.com
Validators : valider les valeurs saisies d’un formulaire
Evénements : gérer les actions utilisateur
Comp. Tomahawk : ajouter de nouveaux composants
Création de composants JSF : étendre la JSF bibliothèque
- M. Baron - Page 390
Configuration : JSF dans le web.xml
Nécessite la configuration du fichier web.xml de façon à ce
que JSF soit pris en compte
Paramétrer le fonctionnement général de l’application : le contrôleur
Identifier la servlet principale : javax.faces.webapp.FacesServlet
Spécifier le nom et le chemin du fichier de configuration
Nom du paramètre : javax.faces.application.CONFIG_FILES
Exemple : /WEB-INF/faces-config.xml
Spécifie où l’état de l’application doit être sauvé
Nom du paramètre : javax.faces.STATE_SAVING_METHOD
keulkeul.blogspot.com
Valeurs possibles : client ou server
Valider ou pas les fichiers XML
Nom du paramètre : com.sun.faces.validateXml
Valeurs possibles : true ou false (défaut : false)
JSF - M. Baron - Page 391
Configuration : JSF dans le web.xml
Indique si les objets développés tels que les Beans, les
composants, les validators et les converters doivent être
créés au démarrage de l’application
Nom du paramètre : com.sun.faces.verifyObjects
Valeurs possibles : true ou false (défaut : false)
La servlet principale est le point d’entrée d’une application JSF
On trouve plusieurs manières de déclencher des ressources JSF
Préfixe /faces/
Suffixes *.jsf ou *.faces
Exemples (le contexte de l’application est myAppli)
keulkeul.blogspot.com
http://localhost/myAppli/faces/index.jsp
http://localhost/myAppl/index.jsf
Avec Struts nous utilisions généralement le
suffixe « .do » pour atteindre le contrôleur
JSF - M. Baron - Page 392
Configuration : JSF dans le web.xml
Exemple : paramétrer une application Web de type JSF
Utilisation de context-param pour
paramétrer le fonctionnement des JSF
...
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param> La Servlet qui gère les entrées
<servlet> au contexte JSF
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
Comment accéder à la Servlet
</servlet-mapping>
keulkeul.blogspot.com
<servlet-mapping> « Faces Servlet »
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
...
web.xml
JSF - M. Baron - Page 393
Configuration : accès restreints aux pages JSP
Quand une page JSP utilise des composants JSF elle doit être
traitée obligatoirement par la Servlet principale
http://localhost/myAppli/faces/index.jsp : appel de la page index.jsp
Dans le cas où une page JSP est appelée directement sans
passer par la Servlet principale une erreur est générée
http://localhost/myAppli/index.jsp : erreur !!!
Empêcher donc les clients d’accéder directement aux pages
JSP qui exploitent des composants JSF
keulkeul.blogspot.com
Solutions
Utiliser la balise security-constraint dans le fichier web.xml
Déclarer chaque page JSP qui doit être protégée (celles qui utilisent
des composants JSF) 394
JSF - M. Baron - Page
Configuration : accès restreints aux pages JSP
Exemple : restreindre l’accès aux pages JSP
...
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param> Ajouter la balise security-constraint
... dans le fichier web.xml
<securiy-constraint>
<web-resource-collection>
<web-resource-name>No-JSF-JSP-Access</web-resource-name>
<url-pattern>/welcome.jsp</url-pattern>
<url-pattern>/form1.jsp</url-pattern>
<url-pattern>/accepted.jsp</url-pattern>
<url-pattern>/refused.jsp</url-pattern>
<url-pattern>...</url-pattern>
</web-resource-collection> Les pages JSP qui utilisent
<auth-constraint> des composants JSF
keulkeul.blogspot.com
<description>Pas de rôles, donc pas d’accès direct</description>
</auth-constraint>
</security-constraint>
...
Protéger efficacement toutes les pages
JSP qui utilisent des composants JSF
JSF - M. Baron - Page 395
Configuration : le fichier contrôleur « faces-config.xml »
Le fichier gérant la logique de l’application web s’appelle par
défaut faces-config.xml
Il est placé dans le répertoire WEB-INF au même niveau que
web.xml
Il décrit essentiellement six principaux éléments :
les Beans managés <managed-bean>
les règles de navigation <navigation-rule>
les ressources éventuelles suite à des messages <message-bundle>
la configuration de la localisation <resource-bundle>
la configuration des Validators et des Converters <validator>
<converter>
keulkeul.blogspot.com
d’autres éléments liés à des nouveaux composants JSF <render-kit>
Le fichier de configuration est un fichier XML décrit par une
DTD. La balise de départ est <faces-config>
(version 1.1) JSF - M. Baron - Page 396
Configuration : le fichier contrôleur « faces-config.xml »
La description de l’ensemble des balises peut être trouvée
http://www.horstmann.com/corejsf/faces-config.html
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<navigation-rule>
...
Description de fonctionnement
</navigation-rule>
de l’application JSF
<managed-bean>
...
keulkeul.blogspot.com
</managed-bean>
</faces-config>
La version 1.2 de JSF utilise un
schéma au lieu d’une DTD
JSF - M. Baron - Page 397
Configuration : balises personnalisées dans les JSP
Les composants JSF sont utilisés dans les pages JSP au
moyen de balises personnalisées dédiées aux JSF
CORE : noyau qui gère les vues Le détail de CORE et HTML
HTML : composants JSF sera donné plus tard
Description des balises personnalisées Core et HTML
http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/tlddocs
http://www.horstmann.com/corejsf/jsf-tags.html
Possibilité d’utiliser d’autres balises (Tomahawk, ADF Faces)
Les composants JSF doivent être encadrés par une vue JSF
déclarée par la balise <core:view>
keulkeul.blogspot.com
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core" %>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html" %>
...
<core:view> Utilisation des
composants JSF
... Possibilité d’utiliser des balises
</core:view>
...
HTML classiques c’est du JSP!!!
JSF - M. Baron - Page 398
Configuration : JSF et Tomcat
Pour exploiter et déployer une application WEB avec JSF il
faut
des librairies JSF (Apache ou Sun) et JSTL
configurer le fichier web.xml selon la version de JSF
Les librairies peuvent être copiées soit en locale à l’appli web
sont en globale dans le répertoire Tomcat
*.html, *.jsp, ...
bin
Globale à
WEB-INF web.xml l’application jsf-api.jar
MyApp faces-config.xml
lib
keulkeul.blogspot.com
jsf-impl.jar
classes ... jstl-1.2.jar
jsf-api.jar …
jsf-impl.jar
lib
jstl-1.2.jar
…
conf
Locale à Tomcat
classes
l’application
JSF - M. Baron - Page 399
Configuration : JSF et Tomcat
Selon la version et le serveur d’application, le fichier web.xml
doit être complété (Tomcat 6 pour nos tests)
Pour la version 1.1.5 de JSF (MyFaces)
<web-app ...>
...
<listener>
<listener-class>
org.apache.myfaces.webapp.StartupServletContextListener
</listener-class>
</listener>
</web-app>
Pour la version 1.2 de JSF (Sun) web.xml
<web-app ...>
...
<listener>
<listener-class>
keulkeul.blogspot.com
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
<listener>
<listener-class>
com.sun.faces.application.WebappLifecycleListener
</listener-class>
</listener>
</web-app>
JSF - M. Baron - Page 400
Le premier exemple « Hello World avec JSF »
Exemple : afficher le message « Hello World » avec JSF
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World avec JSF</title>
</head>
<body>
<core:view>
<h1><html:outputText value="Hello World avec JSF" /></h1><br>
La même chose avec du HTML : <h1>Hello World avec JSF</h1>
</core:view>
</body>
keulkeul.blogspot.com
</html>
welcomeJSF.jsp du projet
HelloWorld
JSF - M. Baron - Page 401
Le premier exemple « Hello World avec JSF »
Exemple (suite) : afficher le message « Hello World » …
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-
app_2_4.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-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<security-constraint>
<display-name>Constraint1</display-name>
<web-resource-collection>
<web-resource-name>No-JSP-JSF-Page</web-resource-name>
keulkeul.blogspot.com
<url-pattern>/welcomeJSF.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>Pas de rôles, donc pas d’accès direct</description>
</auth-constraint>
</security-constraint>
</web-app>
web.xml du projet HelloWorld JSF - M. Baron - Page 402
Le premier exemple « Hello World avec JSF »
Exemple (suite) : afficher le message « Hello World » …
Considérons que la page welcomeJSF.jsp n’est pas protégée et que la
ressource est accédée directement (sans passer par la Servlet principale)
keulkeul.blogspot.com
Retour d’un message d’erreur car les éléments
JSF ne sont pas traités par la Servlet principale
JSF - M. Baron - Page 403
Le premier exemple « Hello World avec JSF »
Exemple (suite) : afficher le message « Hello World » …
Considérons que la ressource welcomeJSF.jsp est protégée et que la
ressource est accédée directement (sans passer par la Servlet principale)
keulkeul.blogspot.com
Retour d’un message d’erreur car la page est protégée
JSF - M. Baron - Page 404
Le premier exemple « Hello World avec JSF »
Exemple (suite) : afficher le message « Hello World » …
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
</faces-config>
keulkeul.blogspot.com
faces-config.xml
Dans cet exemple aucune configuration du projet
est nécessaire. Nous verrons dans la HelloWorld
suite les règles de navigation et la
déclaration de Bean managés
JSF - M. Baron - Page 405
Bean Managé : principe
Rappelons qu’un Bean est une classe Java respectant un
ensemble de directives
Un constructeur public sans argument
Les propriétés d’un Bean sont accessibles au travers de méthodes
getXXX et setXXX portant le nom de la propriété
L’utilisation des Beans dans JSF permet
l’affichage des données provenant de la couche métier
le stockage des valeurs d’un formulaire
la validation des valeurs
l’émission de messages pour la navigation (reçus par faces-config.xml)
keulkeul.blogspot.com
Dans la suite nous verrons que les Beans
peuvent retourner des messages
exploitables par le contrôleur JSF :
principe de la Navigation
JSF - M. Baron - Page 406
Bean Managé : principe
Un Bean managé est un Bean dont la vie est gérée par JSF
et déclaré dans le fichier de configuration faces-config.xml
Définir la durée de vie (scope) d’un Bean
Initialiser les propriétés d’un Bean
A la différence des Beans utilisés dans Struts, les Beans
managés de JSF n’héritent pas d’une classe particulière
Les classes sont stockées dans le répertoire WEB-INF/classes
*.html, *.jsp, ...
WEB-INF web.xml, faces-config-xml
keulkeul.blogspot.com
classes Beans
lib Librairie JSF
JSF - M. Baron - Page 407
Bean managé : configuration dans faces-config.xml
Pour créer un Bean managé il faut le déclarer dans le fichier
de configuration de JSF à l’aide de la balise <managed-bean>
Trois éléments essentiels sont à préciser
<managed-bean-name> définit un nom qui servira d’étiquette quand le
Bean sera exploité dans les pages JSP
<managed-bean-class> déclare le nom de la classe de type
package.class
<managed-bean-scope> précise le type de scope utilisé pour le Bean
none, application, session, request
... Etudiée dans la
<navigation-rule>...</navigation-rule> partie Navigation
keulkeul.blogspot.com
<managed-bean>
<managed-bean-name>MyBean</managed-bean-name>
<managed-bean-class>mypackage.MyFirstBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
...
faces-config.xml JSF - M. Baron - Page 408
Bean managé : JSP, Bean et Expression Language (EL)
Un formulaire JSF doit être construit dans un groupe défini
par la balise <html:form> ... </html:form>
ACTION est automatiquement à SELF (URL courante)
METHOD est obligatoirement POST
Utilisation de composants JSF pour saisir des informations
<html:inputText> pour la balise HTML <INPUT TYPE="Text">
<html:inputSecret> pour la balise <INPUT TYPE="PASSWORD">
<html:commandButton> pour la balise <INPUT TYPE="SUBMIT">
La balise <html:commandButton> contient un attribut action
qui permet d’indiquer un message traité par les règles de
keulkeul.blogspot.com
navigation définies dans faces-config.xml
Nous verrons dans la partie
Navigation le traitement de la valeur
indiquée dans l’attribut action JSF - M. Baron - Page 409
Bean managé : JSP, Bean et Expression Language (EL)
Exemple : formulaire JSP utilisant des composants JSF
<%@page contentType="text/html"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html"%>
<html>
<head>
<title>Premier formulaire avec JSF</title>
</head>
<body>
<core:view>
<html:form>
<html:outputText value="Adresse Email " /><html:inputText/><br>
<html:outputText value="Mot de Passe " /><html:inputSecret/><br>
<html:commandButton value="Connecter" />
</html:form>
</core:view>
</body>
</html>
keulkeul.blogspot.com
beanform1.jsp du projet
ManagedBean
JSF - M. Baron - Page 410
Bean managé : JSP, Bean et Expression Language (EL)
Les Expressions Languages (EL) sont utilisées pour accéder
aux éléments du Bean dans les pages JSP
Un EL permet d’accéder simplement aux Beans des différents
scopes de l’application (page, request, session et application)
Forme d’un Expression Language JSF
#{expression}
Les EL JSF sont différentes des EL JSP qui utilisent la notation
keulkeul.blogspot.com
${expression}
Une EL est une expression dont le résultat est évaluée au
moment où JSF effectue le rendu de la page JSF - M. Baron - Page 411
Bean managé : JSP, Bean et Expression Language (EL)
L’écriture #{MyBean.value} indique à JSF
de chercher un objet qui porte le nom de MyBean dans son contexte
puis invoque la méthode getValue() (chercher la propriété value)
Le nom de l’objet est déterminé dans le fichier
faces-config.xml
...
<navigation-rule>...</navigation-rule>
<managed-bean>
<managed-bean-name>MyBean</managed-bean-name>
<managed-bean-class>mypackage.MyFirstBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
keulkeul.blogspot.com
...
Possibilité d’accéder à un objet contenu dans le Bean
#{MyBean.myobject.value} : propriété value de myobject contenu
dans MyBean JSF - M. Baron - Page 412
Bean managé : JSP, Bean et Expression Language (EL)
JSF définit un ensemble d’objets implicites utilisables dans les
Expressions Languages :
param : éléments définis dans les paramètres de la requête HTTP
param-values : les valeurs des éléments param
cookies : éléments définis dans les cookies
initParam : paramètres d’initialisation de l’application
Etudiée au niveau de la
requestScope : éléments défini dans la requête
partie cycle de vie
keulkeul.blogspot.com
facesContext : instance de la classe FacesContext
View : instance de UIViewRoot
Expliquer au niveau des
composants graphiques JSF - M. Baron - Page 413
Bean managé : JSP, Bean et Expression Language (EL)
Exemple : objets implicites JSF dans une JSP
<html>
<...>
<body>
<core:view>
<p><html:outputText
value="#{param.test}" /></p>
<p><html:outputText
value="#{cookie.JSESSIONID.value}" /></p>
<p><html:outputText
value="#{facesContext.externalContext.requestPathInfo}" /></p>
<p><html:outputText
value="#{facesContext.externalContext.requestServletPath}" /></p>
</core:view>
</body>
</html>
keulkeul.blogspot.com
implicitobjects.jsp du
projet ImplicitObjects
JSF - M. Baron - Page 414
Bean managé : modifier/afficher la propriété d’un Bean
Un formulaire regroupe un ensemble de composants
contenant chacun une valeur (attribut value)
Chaque valeur d’un composant peut être stockée dans une
propriété du Bean
Pour définir une propriété dans un Bean
Créer l’attribut correspondant à la propriété
Définir des méthodes set et get pour accéder en lecture et en écriture
aux propriétés
Pour stocker la valeur d’un composant vers le Bean ou
keulkeul.blogspot.com
afficher la valeur d’une propriété dans un composant :
utilisation des EL dans l’attribut value du composant JSF
JSF associe automatiquement la propriété d’un Bean à la
valeur d’un composant JSF - M. Baron - Page 415
Bean managé : modifier/afficher la propriété d’un Bean
Exemple : gestion d’un formulaire « email et mot de passe »
package beanPackage;
public class RegistrationBean {
private String email = "user@host";
private String password = "";
public String getEmail() {
return email;
} RegistrationBean.java du
public void setEmail(String t) { projet ManagedBean
this.email = t;
possède deux propriétés et
}
public String getPassword() { des modifieurs et accesseurs
keulkeul.blogspot.com
return password;
}
public void setPassword(String t) {
this.password = t;
}
}
JSF - M. Baron - Page 416
Bean managé : modifier/afficher la propriété d’un Bean
Exemple (suite) : gestion d’un formulaire …
... EL pour accéder à la
<core:view> propriété email
<html:form>
<html:outputText value="Adresse Email "/>
<html:inputText value="#{registrationbean.email}"/><br>
<html:outputText value="Mot de Passe "/>
<html:inputSecret value="#{registrationbean.password}"/><br>
<html:commandButton value="Connecter" />
</html:form>
</core:view> EL pour accéder à la
</body> propriété password
</html>
keulkeul.blogspot.com
beanform2.jsp du projet
ManagedBean
Affichage de la valeur
d’initialisation du Bean
JSF - M. Baron - Page 417
Bean managé : modifier/afficher la propriété d’un Bean
Exemple (suite) : gestion d’un formulaire …
<faces-config>
<managed-bean>
<managed-bean-name>
Identifiant utilisé pour accéder
registrationbean
</managed-bean-name> au Bean défini par la classe
<managed-bean-class> beanpackage.RegistrationBean
beanpackage.RegistrationBean
</managed-bean-class>
<managed-bean-scope>
request
</managed-bean-scope>
</managed-bean>
keulkeul.blogspot.com
</faces-config>
faces-config.xml du projet
ManagedBean
JSF - M. Baron - Page 418
Bean managé : initialisation des propriétés d’un Bean
Possibilité d’initialiser la propriété d’un Bean dans
le Bean lui-même
le fichier faces-config.xml
Dans le fichier faces-config.xml utilisation des EL
Accès aux objets implicites
Accès aux autres Beans managés
L’initialisation d’un Bean est obtenue à l’intérieur de la balise
<managed-bean> dans la balise <managed-property>
Chaque propriété à initialiser est déclarée par la balise
<property-name> contenu dans <managed-property>
keulkeul.blogspot.com
Une propriété peut être de différentes types
List : définit une propriété de type liste
Map : définit une propriété de type Map (une clé / valeur)
Value : définit une propriété sur une valeur
JSF - M. Baron - Page 419
Bean managé : initialisation des propriétés d’un Bean
Si la propriété est de type List, l’initialisation des valeurs de la
propriété est effectuée dans la balise <list-entries>
Dans la balise <list-entries> deux informations sont à indiquer
<value-class> : le type d’objet contenu dans la liste
<value> : une valeur dans la liste (autant d’élément de la liste)
<managed-bean>
...
<managed-property>
<property-name>cities</property-name>
<list-entries>
<value-class>java.lang.String</value-class>
keulkeul.blogspot.com
<value>Poitiers</value>
<value>Limoges</value>
<value>Viroflay</value>
</list-entries>
</managed-property>
</managed-bean>
JSF - M. Baron - Page 420
Bean managé : initialisation des propriétés d’un Bean
Si la propriété est de type Map, l’initialisation des valeurs de la
propriété est effectuée dans la balise <map-entries>
Dans la balise <map-entries> trois informations sont à donner
<key-class> : le type de la clé
<value-class> : le type d’objet contenu dans la Map
<map-entry> : contient une clé et une valeur
La balise <map-entry> contient deux informations
<key> : la clé
<value> : la valeur associée à la clé
<managed-property>
keulkeul.blogspot.com
<property-name>prices</property-name>
<map-entries>
<map-entrie>
<key>SwimmingPool High Pressure</key>
<value>250</value>
</map-entrie>
</map-entries>
JSF - M. Baron - Page 421
Bean managé : initialisation des propriétés d’un Bean
Si la propriété est de type Value, l’initialisation de la valeur de
la propriété est effectuée dans la balise <value>
<managed-bean>
...
<managed-property>
<property-name>email</property-name>
<value>user@host</value>
</managed-property>
<managed-property>
<property-name>name</property-name>
<value>your name</value>
</managed-property>
faces-config.xml du
keulkeul.blogspot.com
<managed-property>
<property-name>adress</property-name> projet
<value>your adress</value> ManagedBean
</managed-property>
</managed-bean>
JSF - M. Baron - Page 422
Bean managé : initialisation des propriétés d’un Bean
Exemple : initialisation de propriétés dans faces-config.xml
</managed-bean>
<managed-bean>
<managed-bean-name>registrationbeanbis</managed-bean-name>
<managed-bean-class>
beanPackage.RegistrationBeanBis
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>email</property-name>
<value>#{registrationbean.email}</value>
</managed-property> Utilisation d’une EL pour
<managed-property>
accéder au Bean défini
<property-name>adress</property-name>
<value>Your Adress</value> par registrationbean
keulkeul.blogspot.com
</managed-property>
</managed-bean>
faces-config.xml du projet
ManagedBean
JSF - M. Baron - Page 423
Bean managé : initialisation des propriétés d’un Bean
Exemple (suite) : initialisation de propriétés …
<html>
<head>
<title>Troisième formulaire JSF avec un Bean Managé ...</title>
</head>
<body>
<core:view>
<html:form>
<html:outputText value="Adresse Email "/>
<html:inputText value="#{registrationbeanbis.email}"/><br>
<html:outputText value="Adresse Postale "/>
<html:inputTextvalue="#{registrationbeanbis.adress}"/><br>
<html:commandButton value="Connecter" />
</html:form>
</core:view>
</body>
</html>
keulkeul.blogspot.com
beanform3.jsp du projet
ManagedBean
JSF - M. Baron - Page 424
Cycle de vie d’une JSF : généralités
Réponse Réponse
Complète Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
Réponse Réponse
Complète Complète
Réponse Render Invoke Update
Process Process
Response Application Model
Faces Events Events
Values
keulkeul.blogspot.com
Erreurs de Conversion
Erreurs de Conversion
et / ou de Validation
Détaillé au fur et à mesure : conversion,
validation, événements, … JSF - M. Baron - Page 425
Cycle de vie d’une JSF : généralités
Restore View : JSF reconstruit l’arborescence des compo-
sants qui composent la page.
Apply Requests : les valeurs des données sont extraites de
la requête
Process Validations : procède à la validation des données
Update model values : mise à jour du modèle selon les
valeurs reçues si validation ou conversion réussie
keulkeul.blogspot.com
Invoke Application : les événements émis de la page sont
traités. Elle permet de déterminer la prochaine page
Render Response : création du rendue de la page
JSF - M. Baron - Page 426
Navigation : configuration de faces-config.xml
Le fichier de faces-config.xml joue le rôle de contrôleur, il
décide de la ressource qui doit être appelée suite à la
réception d’un message
Les messages sont des simples chaînes de caractères
Utilisation de la balise <navigation-rule> pour paramétrer les
règles de navigation
La balise <from-view-id> indique la vue source où est
effectuée la demande de redirection. La vue peut être un :
Formulaire (action de soumission)
Lien hypertext
keulkeul.blogspot.com
Pour chaque valeur de message une page vue de direction est
indiquée dans la balise <navigation-case>
<from-outcome> : la valeur du message
<to-view-id> : la vue de direction JSF - M. Baron - Page 427
Navigation : statique ou dynamique
JSF implémente une machine à états pour gérer la navigation
entre des pages JSF
Pour schématiser nous distinguons deux sortes de navigation
Navigation statique
Navigation dynamique
Navigation statique
La valeur de l’outcome est connue au moment de l’écriture de la JSP
Navigation dynamique
La valeur de l’outcome est inconnue au moment de l’écriture de la JSP
keulkeul.blogspot.com
Elle peut être calculée par un Bean Managé ou autre chose …
Remarques
Si une valeur d’outcome est inconnue la même page JSP est rechargée
Si la valeur vaut null la page JSP est rechargée JSF - M. Baron - Page 428
Navigation statique : exemples
Exemple : redirection statique à partir d’un formulaire
...
<html>
<head>
<title>Redirection Statique à partir d’un formulaire</title>
</head>
<body>
<core:view>
<html:form>
<html:outputText value="Nom : " />
<html:inputText value="#{beancontroller1.name}"/><br>
<html:outputText value="Adresse email : " />
<html:inputText value="#{beancontroller1.email}"/><br>
<html:commandButton value="Connecter" action="register"/>
</html:form>
</core:view>
</body>
</html>
keulkeul.blogspot.com
form1.jsp du projet
Navigation
JSF - M. Baron - Page 429
Navigation statique : exemples
Exemple (suite) : redirection statique …
...
faces-config.xml
<faces-config>
<navigation-rule>
<from-view-id>/form1.jsp</from-view-id>
<navigation-case>
<from-outcome>register</from-outcome>
<to-view-id>/accepted.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html"%>
<html>
... acceptedSimple.jsp
keulkeul.blogspot.com
<body>
du projet Navigation
<core:view>
<h1><html:outputText value="Redirection Réussie" /></h1>
</core:view>
</body>
</html>
N’oubliez pas de protéger toutes les pages
JSP : form1.jsp et acceptedSimple.jsp JSF - M. Baron - Page 430
Navigation dynamique : exemples
Exemple : redirection dynamique à partir d’un Bean
package beanPackage;
public class BeanController2 {
private String email = "user@host";
private String name = "";
... Cette méthode permet de
valider les valeurs et de
public String loginConnect() { choisir le message à retourner
if (this.email.isEmpty()) { au contrôler
Cette méthode retourne JSF
soit « Accepted » soit
return "Rejected";
« Rejected »
}
if (this.name.isEmpty()) {
return "Rejected";
}
Il s’agit ici d’une technique pour
keulkeul.blogspot.com
return "Accepted";
} la validation des informations
} saisies dans un formulaire. Nous
approfondirons cet aspect dans la
BeanController2.java partie Validators
du projet Navigation JSF - M. Baron - Page 431
Navigation dynamique : exemples
Exemple (suite) : redirection dynamique à partir d’un Bean
<faces-config>
<navigation-rule>
<from-view-id>form2.jsp</from-view-id>
<navigation-case>
<from-outcome>Accepted</from-outcome>
<to-view-id>/accepted.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>Rejected</from-outcome>
<to-view-id>/rejected.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>beancontroller2</managed-bean-name>
keulkeul.blogspot.com
<managed-bean-class>
beanPackage.BeanController2 faces-config.xml du
</managed-bean-class> projet Navigation
...
</faces-config>
JSF - M. Baron - Page 432
Navigation dynamique : exemples
Exemple (suite) : redirection dynamique à partir d’un Bean
...
<html>
<head>
<title>Redirection Dynamique à partir d’un formulaire</title>
</head>
<body>
<core:view>
<html:form>
<html:outputText value="Nom : " />
<html:inputText value="#{beancontroller2.name}"/><br>
<html:outputText value="Adresse email : " />
<html:inputText value="#{beancontroller2.email}"/><br>
<html:commandButton value="Connecter"
action="#{beancontroller2.loginConnect}"/>
</html:form>
Accès au Bean identifié par
</core:view>
keulkeul.blogspot.com
</body> beancontroller2 et à la
</html> méthode loginConnect
form2.jsp du projet
Navigation
JSF - M. Baron - Page 433
Navigation dynamique : exemples
Exemple (suite) : redirection dynamique à partir d’un Bean
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html"%>
<html> accepted.jsp du
<head> projet Navigation
<title>Résultat du traitement du formulaire</title>
</head>
<body>
<core:view>
<h1><html:outputText value="Connexion de : "/>
<html:outputText value="#{beancontroller2.name}" /></h1>
</core:view>
</body>
keulkeul.blogspot.com
</html>
Page affichée à la suite de la
soumission. Lecture de la
propriété email du Bean
identifié par beancontroller2
JSF - M. Baron - Page 434
Composants graphiques : présentation
JSF fournit un ensemble de composants graphiques pour la
conception de l’IHM
Un composant JSF est développé à partir de :
classes qui codent le comportement et l’état
classes de « rendu » qui traduisent la représentation graphique
(HTML, FLASH, XUL, …)
classes qui définissent les balises personnalisées relation entre JSP et
classes Java
classes qui modélisent la gestion des événements
keulkeul.blogspot.com
classes qui prennent en compte les Converters et les Validators
Pour exploiter les composants JSF dans les pages JSP, des
balises personnalisées sont utilisées … JSF - M. Baron - Page 435
Composants graphiques : balises CORE
Les balises personnalisées décrites dans CORE s’occupent
d’ajouter des fonctionnalités aux composants JSF
Pour rappel pour avoir un descriptif de l’ensemble des balises
CORE :
http://java.sun.com/javaee/javaserverfaces/1.2/docs/tlddocs
La bibliothèque contient un ensemble de balises
facet : déclare un élément spécifique pour un composant
view et subview : ajoute une vue ou une sous vue
attribute et param : ajoute un attribut ou paramètre à un composant
selectionitem et selectionitems : définit un ou plusieurs éléments
keulkeul.blogspot.com
convertDataTime et convertNumber : conversion de données
validator, validateDoubleRange, … : ajoute des validators
actionListener, valueChangeListener : différents écouteurs
loadBundle : chargement de bundle (fichier de ressources …) - Page
JSF - M. Baron 436
Composants graphiques : balises HTML
Les balises personnalisées décrites dans HTML s’occupent de
la description de l’interface graphique d’une JSF
La spécification JSF décrit un ensemble fini de composants
graphiques. Des bibliothèques tiers (My Faces) proposent des
composants complémentaires
Pour rappel pour avoir un descriptif de l’ensemble des balises
HTML :
http://java.sun.com/javaee/javaserverfaces/1.2/docs/tlddocs
La bibliothèque HTML propose 25 composants qui sont
classifiables en quatre catégories
keulkeul.blogspot.com
Composants de saisies notés I (pour input)
Composants de sorties notés O (pour output)
Composants de commandes notés C (pour commandes)
Composants de regroupement notés R (pour …) JSF - M. Baron - Page 437
Composants graphiques : balises HTML
Famille des regroupements selectOneListbox
form selectOneMenu
panelGroup selectOneRadio
panelGrid Famille des sorties
Famille des saisis column
message et messages
inputHidden
dataTable
inputSecret
outputText
inputText
outputFormat
inputTextArea outputLink
keulkeul.blogspot.com
selectBooleanCheckbox graphicImage
selectManyCheckbox Famille des commandes
selectManyListbox commandButton
selectManyMenu commandLink
JSF - M. Baron - Page 438
Composants graphiques : balises HTML saisis
selectManyCheckbox
selectBooleanCheckbox
intputText
intputSecret
selectManyMenu
selectOneListbox
keulkeul.blogspot.com
selectManyListbox
selectOneMenu
intputTextarea
selectOneRadio JSF - M. Baron - Page 439
Composants graphiques : balises HTML sorties et
commandes
commandButton
commandLink
outputText
graphicImage
dataTable
outputLink
keulkeul.blogspot.com
panelGrid
JSF - M. Baron - Page 440
Composants graphiques : détail balises HTML
Une balise contient généralement trois types d’attributs
Des attributs basiques (description)
Des attributs HTML (description de présentation)
Des attributs DHTML (description pour la partie dynamique)
Selon la nature du composant graphique (saisie, sortie,
commande et autre) le nombre d’attributs varie …
Nous décrirons rapidement les attributs les plus significatifs.
Au fur et à mesure de la présentation des composants
keulkeul.blogspot.com
graphiques nous les détaillerons via des exemples
Les transparents qui suivent sont réalisés dans une optique
de présentation rapide … JSF - M. Baron - Page 441
Composants graphiques : détail balises HTML
Les attributs basiques sont utilisés pour ajouter une descri-
ption spécifique à JSF
Attributs basiques
id : identifiant du composant
binding : association avec un Bean « Backing »
rendered : true composant affiché, false composant caché
styleClass : précise le nom d’une CSS à appliquer au composant
value : valeur du composant
valueChangeListener : associer à une méthode pour le changement de
keulkeul.blogspot.com
valeur
converter : nom de la classe pour une conversion de données
validator : nom de la classe pour une validation de données
required : true valeur obligatoire, false valeur optionnelle
JSF - M. Baron - Page 442
Composants graphiques : détail balises HTML
Les attributs HTML sont utilisés pour modifier l’apparence
graphique d’un composant JSF
Attributs HTML (les plus répandus …)
alt : texte alternatif au cas où le composant ne s'affiche pas
border : bordure du composant
disabled : désactive un composant de saisie ou un bouton
maxlength : maximum de caractères pour un composant de texte
readonly : mode lecture uniquement
keulkeul.blogspot.com
size : taille d'un champ de texte
style : information du style
target : nom de la frame dans lequel le document est ouvert
… (et beaucoup pleins d'autres …) JSF - M. Baron - Page 443
Composants graphiques : détail balises HTML
Les attributs DHTML sont utilisés pour ajouter un aspect
dynamique pour les composants JSF (appel à du JavaScript)
Attributs DHTML La gestion des
événements sera
onblur : élément perd le focus
expliquée dans une
onClick : clique souris sur un élément partie dédiée
ondblClick : double clique souris sur un élément
onfocus : élément gagne le focus
onkeydown, onkeyup : touche clavier enfoncée et relâchée
onkeypress : touche clavier pressée puis relâchée
onmousedown, onmouseup : bouton souris enfoncé et relâché
keulkeul.blogspot.com
onmouseout, onmouseover : curseur souris sort et entre
onreset : formulaire est initialisé
onselect : texte est sélectionné dans un champ de texte
onsubmit : formulaire soumis JSF - M. Baron - Page 444
Composants graphiques : <html:panelGrid>
La balise html:panelGrid est utilisée pour définir l’agencement
des composants visuels
Il ne s’agit donc pas d’un composant visuel mais d’un
conteneur dont l’organisation de ces composants enfants est
réalisée suivant une grille
Les composants enfants sont ajoutés dans le corps
Principaux attributs :
columns : nombre de colonnes de la grille
bgcolor : couleur du fond
keulkeul.blogspot.com
cellpading, cellspacing : espacement entre les cellules
border : border autour de la grille
Le composant html:panelGroup permet de regrouper des
composants dans une cellule (une sorte de fusion)
JSF - M. Baron - Page 445
Composants graphiques : <html:panelGrid>
Exemple : organiser des composants dans une grille
...
<h4>
<html:panelGrid cellspacing="25" columns="2" >
Création d'une
<html:outputText value="Nom : " /> grille avec deux
<html:panelGroup> colonnes
<html:inputText size="15" required="true" />
<html:inputText />
</html:panelGroup>
<html:outputText value="Mot de passe : " /> Regroupement de
<html:inputSecret /> deux composants
</html:panelGrid> dans une cellule
</h4>
keulkeul.blogspot.com
outputcomponent.jsp
du projet
GraphicalComponents
JSF - M. Baron - Page 446
Composants graphiques : <html:dataTable>
Le composant <html:dataTable> permet de visualiser des
données sur plusieurs colonnes et plusieurs lignes
La table peut être utilisée quand le nombre d'éléments à
afficher est inconnu
Les données (la partie modèle) peuvent être gérées par des
Beans
Attributs de la balise :
value : une collection de données (Array, List, ResultSet, …)
var : nom donné à la variable à manipuler pour chaque ligne
keulkeul.blogspot.com
border, bgcolor, width : attributs pour l'affichage
rowClasses, headerClass : attributs pour la gestion des styles (CSS)
Pour chaque colonne de la table, la valeur à afficher est
obtenue par la balise <html:column> JSF - M. Baron - Page 447
Composants graphiques : <html:dataTable>
Exemple : la représentation d'une table JSF
public class Personne {
private String name;
private String firstName;
Personne.java
private String birthName; du projet
private String job; GraphicalComponents
public Personne(String pN, String pF, String pB, String pJ) {
name = pN; firstName = pF; birthName = pB, job = pJ;
}
public String getName() { return name; }
public void setName(String pName) { name = pName; }
public String getFirstName() { return firstName; }
public void setFirstName(String pFirstName) { firstName = pFirstName; }
...
public class DataTableBean {
private List<Personne> refPersonne;
public List getPersonne() {
if (refPersonne == null) {
keulkeul.blogspot.com
refPersonne = new ArrayList<Personne>();
refPersonne.add(new Personne("Baron", "Mickael", "17081976", "Développeur"));
refPersonne.add(new Personne("Dupont", "Marcel", "21041956", "Boucher"));
...
} OutputBean.java
return refPersonne;
} du projet
} GraphicalComponents
JSF - M. Baron - Page 448
Composants graphiques : <html:dataTable>
Exemple (suite) : la représentation d'une table JSF
<core:view>
<html:dataTable value="#{outputbean.personne}" var="personne" border="1"
cellspacing="4" width="60%" >
<html:column>
<html:outputText value="#{personne.name}" />
</html:column>
<html:column>
<html:outputText value="#{personne.firstname}" />
</html:column>
<html:column>
<html:outputText value="#{personne.birthdata}" />
</html:column>
<html:column>
<html:outputText value="#{personne.job}" />
datatablecomponent1.jsp
</html:column>
</html:dataTable> du projet
</core:view> GraphicalComponents
keulkeul.blogspot.com
JSF - M. Baron - Page 449
Composants graphiques : <html:dataTable>
La modification des en-tête et pied de page d'une table est
obtenue en utilisant la balise <core:facet>
<core:facet> s'occupe d'effectuer une relation de filiation
entre un composant et un autre
La filiation consiste à associer le composant <core:facet> est
un composant défini dans le corps de <core:facet>
Attribut du composant <core:facet>
name : nom de la filiation
Pour le composant table deux filiations possibles
header : une filiation entre une colonne et le nom de la colonne
keulkeul.blogspot.com
footer : une filiation entre la table et un nom
caption : une filiation entre le titre de la table et un nom
Le composant de filiation à <core:facet>
doit être absolument un composant JSF JSF - M. Baron - Page 450
Composants graphiques : <html:dataTable>
Exemple : table JSF avec des noms de colonnes
<core:view>
<html:dataTable value="#{outputbean.personne}" var="personne" border="1"
cellspacing="4" width="60%" >
<html:column>
<core:facet name="header" >
<html:ouputText value="Nom" />
</core:facet>
<html:outputText value="#{personne.name}" />
</html:column>
<html:column>
<core:facet name="header" >
<html:verbatim>Prénom</verbatim>
</core:facet>
<html:outputText value="#{personne.firstname}" />
</html:column>
<html:column> Ne sera jamais affiché car
<core:facet name="header" > <core:facet> n'est associé
Date de naissance
à aucun autre composant
keulkeul.blogspot.com
</core:facet>
<html:outputText value="#{personne.birthdata}" />
</html:column>
<html:facet name="footer">
<html:outputText value="#{outputbean.caption}" />
</html:facet> datatablecomponent2.jsp
...
</html:dataTable> du projet
</core:view> GraphicalComponents
JSF - M. Baron - Page 451
Composants graphiques : <html:dataTable>
Pour l'instant, seul l'aspect peuplement des informations a
été traité,<html:dataTable> offre la possibilité de modifier
l'apparence d'une table
Les attributs :
headerClass : style CSS pour la partie en-tête
footerClass : style CSS pour le bas de page
rowClasses : liste de styles CSS pour les lignes
L'attribut rowClasses permet de définir une liste de style CSS
qui sera appliquée pour chaque ligne et répétée autant de
keulkeul.blogspot.com
fois qu'il y a de lignes (définition d'un motif)
Exemple :
Soit la définition suivante : rowClasses="row1, row2, row2"
Répétition du motif row1, row2, row2, row1, row2, …
JSF - M. Baron - Page 452
Composants graphiques : <html:dataTable>
Exemple : table JSF « maquillé »
<head>
<...>
<link href="output.css" tel="stylesheet" type="text/css" >
</head>
<body> datatablecomponent3.jsp
<core:view> du projet GraphicalComponents
<html:dataTable value="#{outputbean.personne}" var="personne" border="1"
cellspacing="4" width="60%" rowClasses="row1,row2"
headerClass="heading" footerClass="footer" >
...
.heading {
</html:dataTable> font-family: Arial, Helvetica, sans-serif;
</core:view> font-weight: bold;
font-size: 20px;
color: black;
background-color:silver;
text-align:center;
}
.row1 {
keulkeul.blogspot.com
background-color:#GFGFGF;
}
.row2 {
Background-color:#CECECE;
.footer { output.css
background-color:#000009;
du projet
Color:white;
} GraphicalComponents
JSF - M. Baron - Page 453
Composants graphiques : <html:dataTable>
Exemple : table JSF avec des composants JSF de saisie
<core:view>
<html:dataTable value="#{outputbean.personne}" var="personne" border="1"
cellspacing="4" width="60%" rowClasses="..." >
<html:column>
<core:facet name="header" >
<html:ouputText value="Nom" />
</core:facet>
<html:inputText value="#{personne.name}" />
</html:column>
<html:column>
<core:facet name="header" >
<html:verbatim>Prénom</verbatim>
</core:facet>
<html:outputText value="#{personne.firstname}" />
</html:column>
</html:dataTable>
</core:view>
keulkeul.blogspot.com
datatablecomponent4.jsp
du projet
GraphicalComponents
JSF - M. Baron - Page 454
Composants graphiques : items
Les balises HTML de type sélection (selectOneRadio,
selectOneMenu) permettent de gérer un ensemble d'éléments
Les éléments peuvent être « peuplés » par :
core:selectItem : affiche un seul élément
core:selectItems : affiche plusieurs éléments
Les balises HTML de sélection s'occupent de gérer la sélection
courante (une ou plusieurs) au travers de leur attribut value
Le type de la sélection courante (retourné au serveur) est
keulkeul.blogspot.com
donné par les éléments de sélection (int, String, Object, …)
La balise html:selectBooleanCheckbox n'est pas concernée
puisqu'elle ne gère qu'un seul élément JSF - M. Baron - Page 455
Composants graphiques : <core:selectItem>
La balise core:selectItem est utilisée pour spécifier un seul
élément
Principaux attributs de la balise core:selectItem :
itemDescription : description (utilisable dans les outils uniquement)
itemDisabled : active ou pas l'item
value : valeur qui pointe vers un objet SelectItem
itemLabel : le texte à afficher
itemValue : la valeur retournée au serveur
Un objet SelectItem est exploitable directement dans un Bean
Différents constructeurs :
keulkeul.blogspot.com
SelectItem(Object value) : constructeur avec une valeur à retourner et
à afficher
SelectItem(Object value, String label) : constructeur avec une valeur à
retourner au serveur et une valeur à afficher JSF - M. Baron - Page 456
Composants graphiques : <core:selectItem>
Exemple : choix d'un élément unique
...
<html:outputText value="Fruit préféré avec SelectItem : " /> intputcomponent.jsp
du projet
<html:selectOneRadio layout="pageDirection" GraphicalComponents
value="#{inputbean.oneRadioValue}" />
<core:selectItem value="#{inputbean.bananeItem}" />
<core:selectItem value="#{inputbean.orangeItem}" />
<core:selectItem itemValue="Clémentine" />
<core:selectItem itemValue="Pomme" /> Utilisation d'un binding
<core:selectItem itemValue="Framboise" /> d'un composant
</html:selectOneRadio> SelectItem
...
public class InputBean {
private String oneRadioValue;
public String getOneRadioValue() {
return oneRadioValue;
}
keulkeul.blogspot.com
public void setOneRadioValue(String p) {
oneRadioValue = p;
}
public SelectItem getBananeItem() {
return new SelectItem("Banane");
}
...
Retourne un objet }
SelectItem JSF - M. Baron - Page 457
Composants graphiques : <core:selectItems>
L’utilisation de la balise core:selectItem peut alourdir l’écriture
des différents éléments des composants de sélection
Cette balise est plutôt adaptée pour un nombre réduits
d’éléments
La balise core:selectItems allège donc l’écriture puisqu’une
seule occurrence de core:selectItems remplace toutes les
occurrences de core:selectItem
L’attribut value est une valeur binding qui pointe vers une
structure de type SelectItem
La structure de type SelectItem peut être de type
keulkeul.blogspot.com
instance unique
map : les entrées sont les itemLabels et itemValues de SelectItem
collection
tableau JSF - M. Baron - Page 458
Composants graphiques : <core:selectItems>
Exemple : choisir de nombreux éléments
html:selectOneRadio html:selectManyListbox
html:selectManyCheckbox
html:selectOneMenu
keulkeul.blogspot.com
html:selectOneListbox
html:selectManyMenu
JSF - M. Baron - Page 459
Composants graphiques : <core:selectItems>
Exemple (suite) : choisir de nombreux éléments
<h4><html:outputText value="Fruit préféré avec SelectItems : " /> Simplification
<html:selectOneRadio value="#{inputbean.oneRadioValue}" /> d’écriture avec la
<code:selectItems value="#{inputbean.oneRadioItems}" /> balise selectItems
</html:selectOneRadio></h4>
<h4><html:outputText value="Ajouter des périphériques : " />
<html:selectManyCheckBox value="#{inputbean.manyCheckBoxValues}" />
<code:selectItems value="#{inputbean.manyCheckBoxItems}" /> Principe identique
</html:selectManyCheckBox ></h4>
quelque soit le
<h4><html:outputText value="Accessoire préféré : " /> composant de
<html:selectOneListBox value="#{inputbean.oneListBoxValues}" />
sélection
<code:selectItems value="#{inputbean.manyAndOneListBoxItems}" />
</html:selectOneListBox></h4>
<h4><html:outputText value="Choisir équipements préférés : " /> Une seule valeur
<html:selectManyListBox value="#{inputbean.manyListBoxValues}" /> sélectionnable
<code:selectItems value="#{inputbean.manyAndOneListBoxItems}" />
</html:selectManyListBox></h4>
Une seule valeur
keulkeul.blogspot.com
<h4><html:outputText value="Choisir une marque de voiture : " /> sélectionnable
<html:selectOneMenu value="#{inputbean.oneMenuValue}" />
<code:selectItems value="#{inputbean.manyAndOneMenuItems}" />
</html:selectOneMenu></h4>
<h4><html:outputText value="Choisir plusieurs marques de voiture : " /> intputcomponent.jsp
<html:selectManyMenu value="#{inputbean.manyMenuValue}" />
<code:selectItems value="#{inputbean.manyAndOneMenuItems}" />
</html:selectManyMenu></h4>
JSF - M. Baron - Page 460
Composants graphiques : <core:selectItems>
Exemple (suite) : choisir de nombreux éléments
public class InputBean {
private SelectItem[] manyCheckBoxItems = new SelectItem[] {
new SelectItem("Clavier"),
new SelectItem("Souris"),
new SelectItem("Ecran"),
new SelectItem("Unité Centrale"),
new SelectItem("Haut Parleur") Utilisées pour
}; peupler les éléments
du composant
private String[] manyCheckBoxValues; selectManyCheckBox
Utilisée pour
public SelectItem[] getManyCheckBoxItems() { afficher la valeur
return manyCheckBoxItems; sélectionnée
} courante
public String[] getManyCheckBoxValues() {
return this.manyCheckBoxValues;
keulkeul.blogspot.com
}
Utilisée pour
public void setManyCheckBoxValues(String[] p) { modifier la valeur
manyCheckBoxValues = p; sélectionnée
} courante
}
JSF - M. Baron - Page 461
Composants graphiques : API JSF
Les classes qui modélisent l'état et le comportement d'un
composant sont les classes principales où dépendent toutes
les autres (rendu, description balises, événements …)
Les composants JSF héritent de la classe de plus haut ni-
veau UIComponent qui est abstraite
La classe UIComponentBase est la classe utilisée comme
implémentation par défaut
Rappelons qu'un composant JSF peut contenir un ensemble
de sous composants (notion de hiérarchie)
keulkeul.blogspot.com
UIComponentBase fournit les services suivants
API pour la gestion du cycle de vie du composant
API pour le rendu du composant
… (complété et détaillé dans la dernière partie) JSF - M. Baron - Page 462
Composants graphiques : API JSF
Hiérarchie des principaux composants JSF
UIComponent
Objet représentant la racine de Classe abstraite
l'arbre après la phase de
Restore View
(plus de détail dans la dernière
UIComponentBase Implémentation par
partie)
défaut
UIViewRoot UIOutput UIInput … UICommand
Associée à la
balise
Associée à la
commandButton
keulkeul.blogspot.com
balise
outputText
HtmlInputText HtmlCommandButton
HtmlOutputText Associée à la
balise
intputText JSF - M. Baron - Page 463
FacesContext : principe
FacesContext permet de représenter toutes les informations
contextuelles associées à la requête et à la réponse
FacesContext est défini par une classe abstraite dont l'instan-
ciation est réalisée (si pas créée) au début du cycle de vie
Notez qu'il y autant d'instances de type FacesContext qu'il y a
de vues JSF
Quand le processus de traitement est terminé, l'objet
FacesContext libère les ressources. L'instance de l'objet est
keulkeul.blogspot.com
conservé (utilisation de la méthode release() )
A chaque nouvelle requête, ré-utilisation des instances de
FacesContext JSF - M. Baron - Page 464
FacesContext : utilisation explicite
FacesContext est essentiellement utilisé par les mécanismes
internes de JSF. Toutefois il est possible d'en extraire des
informations intéressantes
Un objet FacesContext est exploitable dans un Bean ou dans
une JSP via son objet implicite associé
Que peut-on donc faire avec cet objet ?
ExternalContext : accéder aux éléments de la requête et de la réponse
Message Queue : stocker des messages (voir partie suivante)
keulkeul.blogspot.com
ViewRoot : accéder à la racine de l'arbre des composants (UIViewRoot)
Modifier le déroulement du cycle de vie (voir partie événement)
Pleins d'autres choses qui sortent du cadre de ce cours …
JSF - M. Baron - Page 465
FacesContext : utilisation explicite
Exemple : manipuler l'objet FacesContext
package beanPackage;
public class FacesContextBean {
private String name;
public String getName() {
return name;
}
public void setName(String pValue) {
name = pValue;
}
public void apply() {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
System.out.println(context.getRequestPathInfo());
System.out.println(context.getRequestServletPath());
Iterator myIterator = context.getRequestParameterNames();
while(myIterator.hasNext()) {
Object next = myIterator.next();
System.out.println("Nom du paramètre : " + next);
Map requestParameterValuesMap = context.getRequestParameterValuesMap();
keulkeul.blogspot.com
Object tabParameter = requestParameterValuesMap.get((String)next);
if (tabParameter instanceof String[]) {
System.out.println("Valeur du paramètre : " + ((String[])tabParameter)[0]);
}
FacesContextBean.java
}
} du projet
} FacesContext
JSF - M. Baron - Page 466
FacesContext : utilisation explicite
Exemple (suite) : manipuler l'objet FacesContext
...
<body>
<core:view>
<html:form>
<html:inputText value="#{facescontextbean.name}" />
<html:commandButton value="Valider" action="#{facescontextbean.apply}" />
</html:form>
</core:view>
</body>
facescontext.jsp
du projet
FacesContext
keulkeul.blogspot.com
JSF - M. Baron - Page 467
Backing bean : principe
Rappelons que les « Beans Managés » sont utilisés comme
des modèles de vues
L'accès aux « références » des composants de la vue ne peut
se faire directement (assez tordu avec FacesContext)
Il peut être intéressant d’accéder directement à la référence
d’un composant graphique pour en modifier son état (à la
suite d’un événement ou lors du processus de validation)
Le framework JSF offre la possibilité d’encapsuler tout ou
partie des composants qui composent une vue
keulkeul.blogspot.com
Il s’agit d’un type de Bean appelée « Backing Bean » qui
correspond ni plus ni moins à un Bean managé
Un Backing Bean est donc un bean dont certaines propriétés
sont de type UIComponent
JSF - M. Baron - Page 468
Backing bean : principe
Dans le Bean, il faut déclarer des accesseurs et des
modifieurs sur des propriétés de type UIComponent
package beanPackage;
public class BackingBeanExemple {
private String nom; Le « Backing Bean »
private UICommand refCommand; se comporte comme
un Bean Managé
public String getNom() { return nom; }
public void setNom(String pNom) { nom = pNom; }
public void setNomAction(UICommand ref) {
refCommand = ref;
}
public UICommand getNomAction() { Stocker et relayer la
return refCommand; référence d’un
} composant JSF
keulkeul.blogspot.com
Au niveau de la page JSP, la liaison entre le « Backing Bean »
est la vue se fait par l’attribut binding
<html:commandButton binding="#{backingbean.nomAction}" />
JSF - M. Baron - Page 469
Backing bean : principe
Exemple : activer/désactiver un bouton par un Bean
...
<body>
<core:view>
<html:form>
<html:inputText value="#{backingbean.name}" binding="#{backingbean.composantNom}" />
<html:commandButton value="Transformer" binding="#{backingbean.commandButton}"
action="#{backingbean.doProcess}" />
</html:form>
</core:view>
</body>
backingbean1.jsp
du projet
Un bouton activé BackingBean
Une valeur dans un
composant texte Un bouton
keulkeul.blogspot.com
désactivé
La valeur a changé (sans
passer par le Bean) JSF - M. Baron - Page 470
Backing bean : principe
Exemple (suite) : activer/désactiver un bouton par un Bean
package beanPackage;
public class BackingBean {
private String nom = "Baron";
private HtmlInputText composantNom;
private HtmlCommandButton commandButton;
public String getName() {return name; }
public void setName(String pName) {this.name = pName; }
public void setComposantNom(HtmlInputText pCommand) {composantNom = pCommand; }
public HtmlInputText getComposantNom() { return composantNom; }
public void setcommandButton(HtmlCommandButton pCB) {this.commandButton = pCB; }
public HtmlCommandButton getCommandButton() { return this.commandButton; }
public void doProcess() {
if (commandButton != null) {
this.commandButton.setDisabled(true);
keulkeul.blogspot.com
} BackingBean.java
if (composantNom != null) {
du projet
composantNom.setValue("Nouvelle Valeur");
} BackingBean
}
}
JSF - M. Baron - Page 471
Message : manipulation et affichage
Pour l’instant avec un Bean managé il est possible de
Stocker et afficher les valeurs d’un formulaire
Générer les actions pour l’automate de navigation
L’API JSF fournit l’objet FacesMessage pour empiler des
messages qui pourront être afficher dans une page JSP
Un objet FacesMessage est caractérisé par :
Sévérité : SEVERITY_INFO, SEVERITY_WARN, SEVERITY_ERROR
et SEVERIRY_FATAL
Résumé : texte rapide décrivant le message
Détail : texte détaillé décrivant le message
keulkeul.blogspot.com
L’API fournit des modifieurs et accesseurs
setSeverity(FacesMessage.Severity) / getSeverity()
setSummary(String) / getSummary()
setDetail(String) / getDetail() JSF - M. Baron - Page 472
Message : manipulation et affichage
Un objet FacesMessage est donc construit dans une classe
Java (un Bean par exemple)
Pour exploiter des messages dans une page JSP il faut passer
par le contexte courant JSF (FacesContext)
addMessage(String id, FacesMessage message) : ajoute un message à
un composant (défini par id)
Si id est null le message n’est pas associé à un composant
Exemple de construction et transmission d’un FacesMessage :
// Déclaration d’un Message
FacesMessage myFacesMessage = new FacesMessage();
myFacesMessage.setSeverity(FacesMessage.SEVERITY_INFO);
keulkeul.blogspot.com
myFacesMessage.setSummary("Un petit résumé");
myFacesMessage.setDetail("Mon message qui ne sert à rien");
// Transmission d’un Message
FacesContext myFacesContext = FacesContext.getCurrentInstance();
myFacesContext.addMessage(null, myFacesMessage);
JSF - M. Baron - Page 473
Message : manipulation et affichage
La bibliothèque HTML propose deux balises personnalisées
pour afficher les messages
<html:messages> : affiche tous les messages
<html:message> : affiche les messages associés à un id de composant
Les balises contiennent les attributs suivants :
for : indique l’id du composant (uniquement pour message)
showDetail : booléen qui précise si le message est détaillé
showSummary : booléen qui précise si le message est résumé
keulkeul.blogspot.com
tooltip : booléen qui précise si une bulle d’aide est affichée
layout : précise la manière d’afficher les messages. Valeurs possibles
table ou list (par défaut)
JSF - M. Baron - Page 474
Message : manipulation et affichage
Exemple : afficher les messages en un seul bloc
public class BeanMessages {
private String name;
public String getName() { return name; }
public void setName(String p) { this.name = p; }
public void validAction() {
FacesMessage facesMessage = new FacesMessage();
facesMessage.setSeverity(FacesMessage.SEVERITY_INFO);
facesMessage.setSummary("Validation");
if (name == null || name.equals("")) {
facesMessage.setDetail("(nom inconnu)");
} else {
facesMessage.setDetail("(nom connu :" + name + ")");
}
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, facesMessage);
keulkeul.blogspot.com
facesContext.addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_INFO, "Validation 2", "Une seconde ligne"));
}
...
}
BeanMessages du
projet Messages JSF - M. Baron - Page 475
Message : manipulation et affichage
Exemple (suite) : afficher les messages en un seul bloc
<%@taglib prefix="core" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="html" uri="http://java.sun.com/jsf/html"%>
<html>
Affichage sous la
...
<body> forme d’un tableau
<core:view>
<html:form>
<html:messages showDetail="true" layout="table" showSummary="true"/><br>
<html:outputText value="Nom : "/>
<html:inputText value="#{beanmessages.name}"/><br>
<html:commandButton value="Valider" action="#{beanmessages.validAction}"/>
<html:commandButton value="Annuler" action="#{beanmessages.cancelAction}"/>
</html:form>
</core:view>
</body>
</html>
keulkeul.blogspot.com
form1.jsp du projet
Messages
JSF - M. Baron - Page 476
Message : manipulation et affichage
Exemple : afficher les message en plusieurs blocs
<%@taglib prefix="core" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="html" uri="http://java.sun.com/jsf/html"%>
<html> Nécessaire pour identifier form2.jsp du projet
... les sous composants Identifiant du composant Messages
<body>
<core:view> inputText
<html:form id="logonForm">
<html:outputText value="Nom : "/>
<html:inputText id="myIdName" value="#{beanmessage.name}"/><br>
<html:message for="myIdName" tooltip="true" showDetail="true »
showSummary="true"/><br>
Précise que le message est
<html:outputText value="Email : "/> associé à l’id myname
<html:inputText id="myIdEmail" value="#{beanmessage.email}"/><br>
<html:message for="myIdEmail" tooltip="true" showDetail="true »
showSummary="true"/><br>
keulkeul.blogspot.com
<html:commandButton value="Valider" action="#{beanmessage.validAction}"/>
<html:commandButton value="Annuler" action="#{beanmessage.cancelAction}"/>
</html:form>
</core:view>
</body> Les identifiants sont
</html>
utilisés pour « localiser »
les messages JSF - M. Baron - Page 477
Message : manipulation et affichage
Exemple (suite) : afficher les message en plusieurs blocs
public class BeanMessage {
private String name myIdName et
private String email; logonForm sont des
identifiants de
public String getName() { return name; }
public void setName(String p) { this.name = p; } composants
Précise que myIdName
public String getEmail() { return email; }
public void setEmail(String p) { this.email = p; } appartient à logonForm
public void validAction() {
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage("logonForm:myIdName", new
FacesMessage(FacesMessage.SEVERITY_INFO, "Validation Name", "Nom
saisi " + this.name));
facesContext.addMessage("logonForm:myIdEmail", new
keulkeul.blogspot.com
FacesMessage(FacesMessage.SEVERITY_INFO, "Validation Email",
"Email saisi " + this.email));
}
...
}
BeanMessage.java du
projet Messages JSF - M. Baron - Page 478
Message : Internationalisation
faces-config.xml permet de configurer les localisations
acceptées pour l’application WEB dans la balise <application>
Dans <information> deux informations sont à renseigner
<message-bundle> : la ressource contenant les messages localisés
<local-config> : indique la locale par défaut et les locales autorisées
Balise <local-config> deux informations sont à renseigner
<default-locale> : la localisation par défaut
<supported-locale> : la localisation supportée par l’application
...
<application>
keulkeul.blogspot.com
<message-bundle>resources.ApplicationMessage</message-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
<supported-locale>sp</supported-locale>
</locale-config>
faces-config.xml
</application>
JSF - M. Baron - Page 479
Message : Internationalisation
Dans la version 1.2 possibilité de déclarer des variables qui
pointent sur des fichiers properties <resource-bundle>
Dans <resource-bundle> deux informations sont à indiquer
<base-name> : nom de la ressource contenant les messages localisés
<var> : alias permettant d’accéder à la ressource <base-name>
<application>
<resource-bundle>
<base-name>resources.ApplicationMessage</base-name>
<var>bundle</var>
</resource-bundle>
</application>
Dans la version 1.1 le chargement des ressources est effectué
dans la page JSP à l’aide de la balise <core:loadbundle>
keulkeul.blogspot.com
<core:loadBundle basename="resources.ApplicationMessage" var="bundle" />
Les ressources sont exploitées par l’intermédiaire des alias
(attribut var) en utilisant les EL
JSF - M. Baron - Page 480
Message : Internationalisation
Exemple : formulaire utilisant une ressource de localisation
<%@page contentType="text/html"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="core"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="html"%>
<html>
<head> Solution pour
<title>Formulaire JSF avec un Bean Managé</title> la version 1.1
de JSF
</head>
<body>
<core:view>
<core:loadBundle basename="CoursesMessages" var="bundle" />
<html:form>
<html:outputText value="#{bundle.EMAIL_ADRESS_MESSAGE}"/>
<html:inputText value="#{registrationbean.email}"/><br>
<html:outputText value="#{bundle.PASSWORD_MESSAGE}" />
<html:inputSecret value="#{registrationbean.password}"/><br>
keulkeul.blogspot.com
<html:commandButton value="#{bundle.LOGIN_MESSAGE}" />
</html:form>
</core:view>
</body> CoursesMessages_fr.xml
</html>
EMAIL_ADRESS_MESSAGE = Adresse Email managedbeanviewbundle.jsp
PASSWORD_MESSAGE = Mot de Passe
LOGIN_MESSAGE = Connecter JSF - M. Baron - Page 481
Message : Internationalisation
Exemple (bis) : formulaire qui utilise une ressource pour la
localisation version JSF 1.2
<html>
...
<body>
<core:view>
<html:form>
<html:outputText value="#{bundle.EMAIL_ADRESS_MESSAGE}"/>
<html:inputText value="#{registrationbean.email}"/><br>
<html:outputText value="#{bundle.PASSWORD_MESSAGE}" />
<html:inputSecret value="#{registrationbean.password}"/><br>
<html:commandButton value="#{bundle.LOGIN_MESSAGE}" />
</html:form>
</core:view>
</body>
</html>
keulkeul.blogspot.com
<application>
<resource-bundle>
<base-name>resources.ApplicationMessage</base-name>
Solution pour
<var>bundle</var> la version 1.2
</resource-bundle> de JSF
</application>
faces-config.xml JSF - M. Baron - Page 482
Conversion de données : principe
Conversion des données du modèle et de la vue
les paramètres d'une requête sont de type chaînes de caractères
les Beans sont définis par des attributs représentés par des types de
données (int, long, Object, …)
la conversion de données s'assurent alors qu'une chaîne de caractères
peut être traduit en un type de donnée précis
Respect du formatage en entrée et en sortie
Formatage en sortie : affichage d'une date
Afficher la date suivant un format compréhensible par l’utilisateur
(fonction de la localisation et du type d’utilisateur)
keulkeul.blogspot.com
Conformité en entrée : saisie d'une date
Associé à un composant de type saisie
Assurer que l’utilisateur a saisi une chaîne de texte respectant le
format de l’entrée JSF - M. Baron - Page 483
Conversion de données : principe
Les convertisseurs de données sont appelés Converters
Tous les composants affichant une valeur et utilisés lors de
la saisie fournissent une conversion de données
Les converters sont utilisables dans une JSP via une balise
Pour utiliser un converter :
soit utiliser les standards fournis par la bibliothèque JSF dans une JSP
soit le définir programmatiquement (dans un Bean) et l’utiliser dans
une JSP
keulkeul.blogspot.com
Converters standards de la bibliothèque JSF :
core:convertDateTime : pour la conversion de date et d’heure
core:convertNumber : pour la conversion de nombre
JSF - M. Baron - Page 484
Conversion de données : cycle de vie
Réponse Réponse
Complète Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
1
Réponse Réponse
Complète Complète
6 5 2
Réponse Update
Render Process Invoke Process
Response Model
Faces Events Application Events
Values
keulkeul.blogspot.com
4
Erreurs de Conversion
3
Erreurs de Conversion
et / ou de Validation
JSF - M. Baron - Page 485
Conversion de données : cycle de vie
Dans le cas d'un composant de la famille de type UIInput
(par exemple un composant html:inputText)
1 L'étape Process Validations réceptionne les valeurs des para-
mètres (submittedValues) et applique les conversions
2 Si la conversion a réussi, le traitement continu
L'étape Update Model Values modifie le modèle associé (un
Bean par exemple) puis conversion des valeurs du modèle
5 Si la conversion a réussi, continuer processus …
4 Si la conversion a échoué, génération de messages d'erreurs et
keulkeul.blogspot.com
direction étape Render Response 6
3 Si la conversion a échoué, le traitement est abandonné (pas de
changement de page) et des messages d'erreur sont générés et
direction étape Render Response 6
JSF - M. Baron - Page 486
Conversion de données : cycle de vie
Dans le cas d'un composant de la famille de type UIOutput
(par exemple composant html:outputText)
1 L'étape Process Validations et l'étape Update Model Values ne
traitent pas de paramètres car il n'y en a pas …
2 Puis conversion des attributs du modèle présents dans le Bean
5 Si la conversion a réussi, continuer processus …
4 Si la conversion a échoué, génération de messages d'erreur et
direction étape Render Response 6
keulkeul.blogspot.com
La seconde conversion consiste à
s'assurer de la cohérence des
données du modèle et du format
de conversion
JSF - M. Baron - Page 487
Conversion de données : cycle de vie (via l'API)
Tous composants qui implémentent l'interface ValueHolder
peuvent exploiter des Converters (UIOutput et UIInput)
L'implémentation de l'interface ValueHolder doit fournir des
propriétés pour :
Effectuer la conversion via un objet Converter
Stocker la valeur convertie par l'objet Converter
Stocker la valeur propre du composant utilisée pour modifier le
modèle de la vue et fournir une donnée à la réponse
keulkeul.blogspot.com
Ensemble de méthodes
(accesseurs et modifieurs) pour la
manipulation de ces propriétés
JSF - M. Baron - Page 488
Conversion de données : cycle de vie (via l'API)
Un objet Converter fournit deux méthodes :
Object getAsObject(…) throws ConverterException appelée lors de
l'étape Process Validation
String getAsString(…) throws ConverterException appelée après
l'étape Update Model Values
Dans le cas des objets UIInput les valeurs des paramètres
sont stockées dans l'attribut submittedValue (interface
EditableValueHolder)
Par son intermédiaire la
keulkeul.blogspot.com
phase Process
Nous décrirons la classe Validations peut récupérer
Converter au moment de la les valeurs qui étaient issues
création de notre propre des paramètres
converter
JSF - M. Baron - Page 489
Conversion de données : cycle de vie (via l'API)
Processus de conversion par l'API
submittedValue est convertie par getAsObject(…) et stockée dans
localValue (si exception de getAsObject(…) arrêt du processus)
Si localValue != null, sa valeur est transmise à value
value transmet la valeur à une propriété du modèle de la vue
(via un modifieur du Bean)
value récupère la valeur d'une propriété du modèle de la vue
(via un accesseur du Bean)
Si localValue == null, value récupère la valeur d'une propriété du
keulkeul.blogspot.com
modèle
value est convertie par getAsString(…) et envoyée à la réponse (si
exception de getAsString(…) arrêt du processus
JSF - M. Baron - Page 490
Conversion de données : tag convertNumber
La balise core:convertNumber permet la conversion de
chaînes de caractères en valeur numérique
À utiliser dans le corps d’une balise graphique JSF
Différents attributs disponibles
type : type de valeur (number, currency ou percent)
pattern : motif de formatage
(max/min)FractionDigits : (int) nombre maxi/mini sur la décimale
(max/min)IntegerDigits : (int) nombre maxi/mini sur la partie entière
integerOnly : (booléen) seule la partie entière est prise en compte
groupingUsed : (booléen) précise si les caractères de regroupement
keulkeul.blogspot.com
sont utilisés (exemple : « , », « ; », « : », … )
locale : définit la localisation de la conversion
currencyCode : code de la monnaie utilisée pour la conversion
currencySymbol : spécifie le caractère (exclusif avec currencyCode)
JSF - M. Baron - Page 491
Conversion de données : tag convertNumber
Exemple : utilisation d’un converter en « sortie »
<html>
...
converters1.jsp du
<body> projet Converters
<core:view>
<html:form>
<html:outputText value="#{beanconverter1.price}">
<core:convertNumber type="currency" currencyCode="EUR"
minFractionDigits="4" />
</html:outputText>
</html:form>
</core:view> public class BeanConverter1 {
</body> private double price;
</html>
public BeanConverter1() {
this.price = 50.50d;
}
public double getPrice() {
keulkeul.blogspot.com
return price;
}
public void setPrice(double pPrice) {
this.price = pPrice;
}
}
BeanConverter1 du
projet Converters JSF - M. Baron - Page 492
Conversion de données : tag convertNumber
Exemple (suite) : utilisation d’un converter en « entrée »
<html>
...
<body>
<core:view>
<html:form>
Prix :
<html:intputText value="#{beanconverter1.price}" >
<core:convertNumber minFractionDigits="2" />
</html:inputText><br>
<html:commandButton value="Envoyer" />
</html:form>
</core:view>
</body>
</html>
converters2.jsp du
Après la conversion
keulkeul.blogspot.com
projet Converters
Avant la conversion, au
moment de la saisie …
JSF - M. Baron - Page 493
Conversion de données : tag convertDateTime
La balise core:convertDateTime permet la conversion de
chaînes de caractères en date ou heure
À utiliser également dans le corps d’une balise graphique JSF
<html:outputText value="#{packageBean.facturedate}">
<core:convertDateTime type="date" dateStyle="long"/>
</html:outputText>
Différents attributs disponibles
type : type de valeur (date, time ou both)
keulkeul.blogspot.com
dateStyle : style possible de la date (short, medium, long, full, both)
timeStyle : style possible de l’heure (short, medium, long, full, both)
Pattern : motif utilisé pour une Date
Locale : choix de la localisation
JSF - M. Baron - Page 494
Conversion de données : tag convertDateTime
Exemple : utilisation d’un converter date en « entrée »
...
<body> converters3.jsp du
<core:view>
<html:form>
projet Converters
<html:outputText value="Nom : " />
<html:inputText value="#{beanconverter2.name}" /><br>
<html:outputText value="Nombre de tickets : " />
<html:inputText value="#{beanconverter2.tickets}" >
<core:convertNumber type="number" integerOnly="true" />
</html:inputText><br>
<html:outputText value="Date : " />
<html:inputText value="#{beanconverter2.date}">
<core:convertDateTime type="date" dateStyle="medium" />
</html:inputText>
<html:commandButton value="Valider" />
</html:form>
keulkeul.blogspot.com
</core:view>
</body>
</html>
JSF - M. Baron - Page 495
Conversion de données : tag convertDateTime
Exemple (suite) : utilisation d’un converter Date en « entrée »
public class BeanConverter2 {
private long tickets;
private String name;
private Date date;
public BeanConverter2() {
tickets = 50;
name = "Mon Nom";
date = new Date();
}
public long getTickets() { return tickets; }
public void setTickets(long pTickets) { tickets = pTickets; }
public String getName() { return name; }
public void setName(String pName) { name = pName; }
keulkeul.blogspot.com
public Date getDate() { return date; }
public void setDate(Date pDate) { date = pDate; }
}
BeanConverter2.java
du projet Converters
JSF - M. Baron - Page 496
Conversion de données : messages
Dans le cas où des erreurs de conversion sont provoquées,
des messages sont ajoutés au FacesContext
En utilisant les balises html:message et html:messages
possibilité d'afficher un message précis ou l'ensemble
Généralement à chaque composant est associé un id, ce qui
permettra de localiser précisément l'origine de l'erreur
Converters2.jsp du
Exemple : projet Converters
keulkeul.blogspot.com
...
<html:outputText value="Prix : " />
<html:intputText id="priceId" value="#{beanconverter1.price}" >
<core:convertNumber minFractionDigits="2" />
</html:inputText><html:message for="priceId" /><br>
<html:commandButton value="Envoyer" />
...
JSF - M. Baron - Page 497
Conversion de données : messages
Exemple : converter date en « entrée » avec messages
...
<core:view> converters3.jsp du
<html:form>
<html:outputText value="Nomprojet
: " />Converters
<html:inputText value="#{beanconverter2.name}" /><br>
<html:outputText value="Nombre de tickets : " />
<html:inputText id="ticketsId" value="#{beanconverter2.tickets}" >
<core:convertNumber type="number" integerOnly="true" />
</html:inputText><html:message for="ticketsId" /><br>
<html:outputText value="Date : " />
<html:inputText id="dateId" value="#{beanconverter2.date}">
<core:convertDateTime type="date" dateStyle="medium" />
</html:inputText><html:message for="dateId" /><br>
<html:outputText value="Liste des messages : " /><br>
<html:messages />
<html:commandButton value="Valider" />
</html:form>
keulkeul.blogspot.com
</core:view>
</body>
</html>
JSF - M. Baron - Page 498
Conversion de données : messages personnalisés
Les messages sont déclarés par des clés stockées dans un
fichier ressource dont le nom dépend de la localisation
Les fichiers ressources (fichier au format properties) sont
stockés dans le répertoire javax.faces de la librairie
implémentation de JSF (myfaces-impl-1.x.x.jar)
Pour modifier un message pour un converter donné
Créer un fichier properties dans le répertoire source
keulkeul.blogspot.com
Déclarer le fichier properties dans le faces-config.xml
Copier les clés à redéfinir
Modifier la valeur du texte dans les clés
JSF - M. Baron - Page 499
Conversion de données : messages personnalisés
Exemple : modification des messages d'erreurs de conversion
...
<application>
<messsage-bundle>beanPackage.MyMessages</message-bundle>
faces-config.xml du
</application>
</faces-config> projet Converters
...
javax.faces.convert.NumberConverter.CONVERSION = Problème pour le champs
"Nombre de tickets"
Javax.faces.convert.NumberConverter.CONVERSION_detail = "{0}" : La donnée
n'est pas un nombre valide
...
*.html, *.jsp, ...
keulkeul.blogspot.com
web.xml
MyApp
WEB-INF
faces-config.xml MyMessages.properties
classes MyMessages.properties
JSF - M. Baron - Page 500
Conversion de données : attribut immediate
Rappelons que toute requête JSF passe obligatoirement par
un traitement défini par le cycle de vie JSF
La conversion de données est obligatoirement traitée par le
cycle de vie JSF même si par exemple une requête donnée
n’est pas de valider un formulaire (annuler le traitement)
Si une requête est d’annuler la saisie du formulaire (redirec-
tion vers une autre page), le processus effectuera toujours la
conversion de données de tous les composants d’une vue JSF
Il peut donc être utile de passer outre le processus de con-
keulkeul.blogspot.com
version : utilisation de l’attribut immediate pour une balise de
composant qui doit soumettre le formulaire
La présence de l’attribut immediate (valeur à true) modifie le
déroulement du cycle de vie d’une requête JSF JSF - M. Baron - Page 501
Conversion de données : attribut immediate
Le composant passé à immediate sera géré en premier dans
le cycle de vie
Le fonctionnement donné ci-dessous ne concerne que les
composants de type Command (CommandButton par exemple)
Après la phase Apply Request Values, le traitement de la requête
va être redirigé directement vers Render Response
De cette manière les phases Process Validations, Update Model
Values, Invoke Application ne sont pas exécutées
Il n’y a donc pas de conversion, ni de modification dans le
modèle
Les différentes saisies de l’utilisateur ne sont jamais traitées
keulkeul.blogspot.com
et il n’y a donc pas d’erreurs qui pourraient bloquées
l’utilisateur Une explication détaillée de l’effet de bord de
immediate (composant Input et Command) est
donnée dans la partie événement 502
JSF - M. Baron - Page
Conversion de données : attribut immediate
Réponse Réponse
Complète Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
Quand
immediate == true
Réponse Réponse
Complète Complète
Réponse Update
Render Process Invoke Process
Response Model
Faces Events Application Events
Values
keulkeul.blogspot.com
Erreurs de Conversion
Cycle de vie valable ssi le
composant concerné par l’attribut Erreurs de Conversion
immediate est de type Commandet / ou de Validation
JSF - M. Baron - Page 503
Conversion de données : attribut immediate
Exemple : passer outre le processus de conversion
Les problèmes de
conversion ne sont pas
pris en compte
keulkeul.blogspot.com
Les problèmes de conversion
sont pris en compte. Obligation
de saisir correctement les
données pour annuler
JSF - M. Baron - Page 504
Conversion de données : attribut immediate
Exemple (suite) : passer outre le processus de conversion
...
<core:view>
<html:form>
...
<html:outputText value="Date : " />
<html:inputText id="dateId" value="#{beanconverter2.date}">
<core:convertDateTime type="date" dateStyle="medium" />
</html:inputText><html:message for="dateId" /><br>
<html:outputText value="Liste des messages : " /><br>
<html:messages />
<html:commandButton value="Valider" />
<html:commandButton value="Annuler (sans immediate)" action="CancelAction" />
<html:commandButton value="Annuler (avec immediate)" action="CancelAction"
immediate="true" />
</html:form>
</core:view> <faces-config>
<navigation-rule>
<from-view-id>*</from-view-id>
keulkeul.blogspot.com
<navigation-case>
convertersImmadiate.jsp <from-outcome>CancelAction</from-outcome>
du projet Converters <to-view-id>/index.jsp</to-view-id>
</navigation-case>
</navigation-rule>
...
faces-config.xml du </faces-config>
projet Converters
JSF - M. Baron - Page 505
Conversion de données : conversion personnalisée
Pour bientôt …
Réalisation de son propre Converter
keulkeul.blogspot.com
JSF - M. Baron - Page 506
Validation de données : principe
L’objectif de la validation de données est de s’assurer que les
informations qui ont été converties sont valides
Les objets utilisés pour la validation sont appelés Validators
Tous les composants utilisés pour la saisie de données
peuvent exploiter des Validators
Pourquoi utiliser des Validators (vérification de surface et de
fond) ?
vérifier la présence de données
keulkeul.blogspot.com
vérifier le contenu d’une données
vérifier la plage de valeurs (entier compris entre 20 et 50)
vérifier le format d’une donnée
… JSF - M. Baron - Page 507
Validation de données : cycle de vie
Réponse Réponse
Complète Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
1
Réponse Réponse
Complète Complète
6 2
Réponse Update
Render Process Invoke Process
Response Model
Faces Events Application Events
Values
keulkeul.blogspot.com
Erreurs de Conversion
3
Erreurs de Conversion
et / ou de Validation
JSF - M. Baron - Page 508
Validation de données : cycle de vie
Composant de la famille de type UIInput (déroulement
proche du processus de conversion)
1 L'étape Process Validations réceptionne les valeurs des paramètres
(submittedValues), applique les conversions et validations
2 Si la conversion et/ou la validation ont réussi, le traitement continu
Voir partie conversion pour détail de la suite …
Si la conversion et/ou la valiation ont échoué, le traitement est
abandonné (pas de changement de page) et des messages d'erreur
sont générés et direction étape Render Response
keulkeul.blogspot.com
De nombreux détails ont été repris
de la partie Converters, pour les
aspects manquants (message,
immediate ) s’y référer
JSF - M. Baron - Page 509
Validation de données : cycle de vie (via l’API)
Les composants implémentant l'interface EditableValueHolder
peuvent exploiter des Validators (UIInput)
EditableValueHolder est une sous interface de ValueHolder
Un objet EditableValueHolder fourni les propriétés pour
ajouter un objet Validator et stocker l’état de validation
Un objet Validator fournit une méthode
validate(FacesContext ct, UIComponent component, Object value)
keulkeul.blogspot.com
throws ValidatorException : en charge d’effectuer la validation
Note : s’il existe une erreur de validation, lancer une exception de
type ValidatorException
JSF - M. Baron - Page 510
Validation de données : principe d’utilisation
Pour utiliser un Validator …
soit utiliser les standards fournis par la bibliothèque JSF
soit définir programmatiquement (dans un Bean)
Utiliser les standards fournis
core:validateDoubleRange : valide les données de type Double
core:validateLongRange : valide les données de type Long
core:validateLength : valide la longueur de type Integer
Dans tous les cas, ces balises fournissent trois attributs
keulkeul.blogspot.com
maximum : valeur maximale
minimum : valeur minimale
binding : évalue une instance du validator en question
JSF - M. Baron - Page 511
Validation de données : validators standards
Exemple : un formulaire, des champs et des validators …
...
<html:form>
<p>
<html:outputText value="Veuillez saisir votre numéro de compte (10
chiffres) : " />
<html:inputText id="compteId" value="#{validatorbean.compte}" >
<core:validateLength maximum="10" minimum="10" />
</html:inputText><html:message for="compteId" />
</p>
<p>
<html:outputText value="Veuillez saisir votre taille (comprise entre 1.2 et
2.0) : " />
<html:inputText id="tailleId" value="#{validatorbean.taille}" >
<core:validateDoubleRange maximum="2.80" minimum="1.20"/>
</html:inputText><html:message for="tailleId" /><br>
<html:commandButton value="Envoyer" />
</p>
keulkeul.blogspot.com
</html:form>
...
standardvalidator.jsp du
projet Validators
JSF - M. Baron - Page 512
Validation de données : validators personnalisés
Nous avons vu que JSF proposait en standard un ensemble
restreint de Validators
Il peut être intéressant de pouvoir développer ses propres
Validators
JSF offre la possibilité de définir programmatiquement les
validators souhaités en utilisant des classes Java
Deux approches de mise en œuvre sont à distinguer :
Utilisation de la balise <core:validator>
keulkeul.blogspot.com
Utilisation de l’attribut validator
Rappelons que la mise en place de validators ne concerne
que les composants de type UIInput JSF - M. Baron - Page 513
Validation de données : validators personnalisés
L’utilisation d’une balise pour lier un validator à un composant
passe par l’implémentation de l’interface Validator
Un objet Validator fournit une méthode
validate(FacesContext ct, UIComponent cp, Object value) throws
ValidatorException : en charge d’effectuer la validation
ct : permet d’accéder au contexte de l’application JSF
cp : référence sur le composant dont la donnée est à valider
value : la valeur de la donnée
L’exception permet d’indiquer si la validation ne s’est pas
keulkeul.blogspot.com
correctement passée
Si exception déclenchée, au développeur à prendre en charge
les messages à retourner via l’objet FacesContext
JSF - M. Baron - Page 514
Validation de données : validators personnalisés
Pour utiliser une classe de type Validator, il faut la déclarer
dans le fichier de configuration faces-config.xml
Il faut identifier dans la balise validator la classe utilisée pour
implémenter le Validator
<validator>
<validator-id>myValidatorId</validator-id>
<validator-class>beanPackage.MyValidator</validator-class>
</validator>
Pour utiliser le validator dans une page JSP, il faut utiliser la
balise <validator> dans le corps d’un composant JSF
keulkeul.blogspot.com
<html:inputText value="#{...}" ... >
<core:validator validatorId="myValidatorId" />
</html:inputText>
JSF - M. Baron - Page 515
Validation de données : validators personnalisés
Exemple : utilisation de la balise <core:validator>
public class PersoValidator implements Validator {
public void validate(FacesContext fc, UIComponent comp, Object ref)
throws ValidatorException {
String myValue = null;
if (fc == null || comp == null || ref == null) {
throw new NullPointerException();
}
PersoValidator.java du
myValue = ref.toString(); projet Validators
final String magicNumber = "123456789";
if (!myValue.equals(magicNumber)) {
throw new ValidatorException(new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"Problème de validation", "numéro magique erroné"));
keulkeul.blogspot.com
}
}
} ... faces-config.xml du
<validator>
<validator-id>myValidatorId</validator-id>
projet Validators
<validator-class>beanPackage.PersoValidator</validator-class>
</validator>
</faces-config>
JSF - M. Baron - Page 516
Validation de données : validators personnalisés
Exemple (suite) : utilisation de la balise <core:validator>
<core:view>
<h4><html:outputText value="Utilisation d'un validator personnalisé :
balise validator" /></h4>
<html:form>
<p>
<html:outputText value="Veuillez saisir votre numéro magique (10
chiffres) : " />
<html:inputText id="compteId" value="#{persobean.magicnumber}" >
<core:validator validatorId="persoValidatorId"/>
</html:inputText><html:message for="compteId" showDetail="true"
showSummary="true"/>
</p>
<p> persotagvalidator.jsp du
<html:commandButton value="Envoyer" />
projet Validators
</p>
</html:form>
</core:view>
keulkeul.blogspot.com
JSF - M. Baron - Page 517
Validation de données : validators personnalisés
L’utilisation de l’attribut validator du composant UIInput à
valider s’appuie sur l’utilisation d’un Bean
Il faut donc fournir à l’attribut validator une expression qui
désigne la méthode de validation
<html:inputText value="#{...}" validator="#{myVal.validate}" ... >
...
</html:inputText>
Le nom de la méthode n’est pas imposé, toutefois elle devra
respecter la signature de la méthode validate() de l’interface
keulkeul.blogspot.com
Validator
L’inconvénient de cette approche est qu’elle est fortement liée
à l’application et il devient difficile de réutiliser le validator
JSF - M. Baron - Page 518
Validation de données : validators personnalisés
Exemple : utilisation de l’attribut validator
public class PersoBeanValidator {
private String magicNumber;
PersoBeanValidator.java
public String getMagicnumber() {
return magicNumber; du projet Validators
}
public void setMagicnumber(String magicNumber) {
this.magicNumber = magicNumber;
}
public void validatePerso(FacesContext fc, UIComponent comp, Object ref)
throws ValidatorException {
String myValue = null;
if (fc == null || comp == null || ref == null) {
throw new NullPointerException();
}
myValue = ref.toString();
keulkeul.blogspot.com
final String magicNumber = "123456789";
if (!myValue.equals(magicNumber)) {
throw new ValidatorException(new FacesMessage(
FacesMessage.SEVERITY_ERROR, "Problème de validation",
"numéro magique erroné"));
}
}
}
JSF - M. Baron - Page 519
Validation de données : validators personnalisés
Exemple (suite) : utilisation de l’attribut validator
<core:view>
<h4><html:outputText value="Utilisation d'un validator personnalisé :
attribut validator" /></h4>
<html:form>
<p><html:outputText value="Veuillez saisir votre numéro magique (10
chiffres) : " />
<html:inputText id="compteId" value="#{persobeanvalidator.magicnumber}"
validator="#{persobeanvalidator.validatePerso}" />
<html:message for="compteId" showDetail="true" showSummary="true"/>
</p>
<p><html:commandButton value="Envoyer" /></p>
</html:form>
</core:view>
persoattributvalidator.jsp
keulkeul.blogspot.com
du projet Validators
JSF - M. Baron - Page 520
Conversion et Validation de données : écriture balises
Pour bientôt …
Ecriture de ses propres balises pour la conversion et la validation
keulkeul.blogspot.com
JSF - M. Baron - Page 521
La gestion des événements : généralités
JSF fournit un mécanisme d’événements se rapprochant des
modèles de gestion d’événements des API Swing et SWT
Certains composants JSF peuvent émettre des événements
C’est une source
Des objets peuvent recevoir des événements
Ce sont des écouteurs (listeners en anglais)
Le mécanisme d’événements est fondé sur la notion d’abon-
nement entre une source et un écouteur
L’API JSF fournit deux types d’événements
keulkeul.blogspot.com
Changement de valeur (ValueChangeEvent) : émis lors du change-
ment de la valeur d’un composant de type UIInput
Lié à une action (ActionEvent) : émis lors d’une action sur un com-
posant de type UICommand JSF - M. Baron - Page 522
La gestion des événements : cycle de vie
Réponse Les ValueChangeListeners Réponse
Complète sont notifiés Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
Réponse Réponse
Complète Complète
Réponse Update
Render Process Invoke Process
Response Model
Faces Events Application Events
Values
keulkeul.blogspot.com
Les ActionListeners
sont notifiés
Erreurs de Conversion
Erreurs de Conversion
et / ou de Validation
JSF - M. Baron - Page 523
La gestion des événements : cycle de vie
Les écouteurs sont notifiés à partir du moment où
la valeur du composant change
le formulaire encapsulant le composant doit être soumis
La notification intervient à différent endroit du cycle de vie
Pour les listeners de type ValueChangeListener la notifica-
tion se produit après la phase de Process Validations
Pour les listeners de type ActionListener la notification se
produit après la phase de Invoke Application
Le traitement d’un écouteur peut affecter le cycle de vie
keulkeul.blogspot.com
Laisser le cycle de vie se dérouler normalement
Passer les différentes phases jusqu’à celle de Render Response
via un appel à FacesContext.renderResponse()
Passer toutes les phases via FacesContext.responseComplete()
JSF - M. Baron - Page 524
La gestion des événements : généralités
Deux approches sont exploitables pour abonner un écouteur
à un composant JSF (type UIInput ou UICommand)
utiliser un attribut (valueChangeListener ou actionListener) de la
balise du composant JSF
<html:inputText onchange="submit()" value="#{databean.name}"
valueChangeListener="#{databean.inputChangement}" />
L’attribut valueChangeListener précise une
méthode appelée si le listener est déclenché
utiliser une balise de CORE (core:valueChangeListener ou
core:actionListener) dans le corps du composant JSF
keulkeul.blogspot.com
<html:inputText onchange="submit()" value="#{databean.name}" >
<core:valueChangeListener type="beanPackage.InputTextChangeListener" />
</html>
Cette classe contient une méthode qui est
appelée si le listener est déclenché JSF - M. Baron - Page 525
La gestion des événements : généralités
Dans les deux cas, il faut fournir les méthodes qui seront
appelées lors du déclenchement des écouteurs
Dans le cas de l’attribut une méthode doit être fournie dans
le Bean (ici inputChangement) avec en paramètre le type
d’événement à traiter (ValueChangeEvent ou ActionEvent)
Dans le cas de la balise une classe implémentant l’interface
ValueChangeListener ou ActionListener doit être fournie
A noter qu’il est possible qu’un Bean (au sens qui stocke des
keulkeul.blogspot.com
valeurs du paramètres) peut implémenter les interfaces des
listeners …
Exemples pour chacun des écouteurs …
JSF - M. Baron - Page 526
La gestion des événements : changement de valeur
Les événements associés au changement de valeur sont
déclenchés quand une valeur d’un composant est modifié (si
la valeur est identique pas de déclenchement)
L’événement transmis est de type ValueChangeEvent
UIComponent getComponent() : renvoie la source
Object getNewValue() : retourne la nouvelle valeur
Object getOldValue() : retourne l’ancienne valeur
…
Préciser un écouteur de type ValueChangeListener
par l’attribut valueChangeListener (sa valeur est une méthode)
keulkeul.blogspot.com
par la balise valueChangeListener (sa valeur est une classe)
Implémentation de l’interface ValueChangeListener
void processValueChange(ValueChangeEvent) : méthode qui traite le
changement de valeur JSF - M. Baron - Page 527
La gestion des événements : changement de valeur
Exemple : abonnement via un « attribut »
<html:form>
<p>
<html:outputText value="Veuillez saisir votre nom : " />
<html:inputText onchange="submit()" value="#{databean.name}"
valueChangeListener="#{databean.inputChangement}" />
</p>
<p>
<html:outputText value="Choisissez votre périphérique : " />
<html:selectOneMenu onchange="submit()" value="#{databean.oneMenuValue}"
valueChangeListener="#{databean.selectChangement}">
<core:selectItems value="#{databean.manyCheckBoxItems}" />
</html:selectOneMenu>
</p>
</html:form>
valueChangeListenerAttribut.jsp
keulkeul.blogspot.com
du projet Event
JSF - M. Baron - Page 528
La gestion des événements : changement de valeur
Exemple (suite) : abonnement via un « attribut »
public class DataBean {
private String menuValue;
private String name= "";
...
public void inputChangement(ValueChangeEvent event) {
System.out.println("InputText");
System.out.println(event.getOldValue());
System.out.println(event.getNewValue());
System.out.println(event.getComponent().getClass());
}
public void selectChangement(ValueChangeEvent event) {
System.out.println("SelectOneMenu");
System.out.println(event.getOldValue());
System.out.println(event.getNewValue());
System.out.println(event.getComponent().getClass());
keulkeul.blogspot.com
}
}
DataBean.java
du projet Event
JSF - M. Baron - Page 529
La gestion des événements : changement de valeur
Exemple : abonnement via une « balise »
<html:form>
<p>
<html:outputText value="Veuillez saisir votre nom : " />
<html:inputText onchange="submit()" value="#{databean.name}" >
<core:valueChangeListener type="beanPackage.InputTextChangeListener"/>
</html:inputText>
</p>
<p>
<html:outputText value="Choisissez votre périphérique : " />
<html:selectOneMenu onchange="submit()" value="#{databean.oneMenuValue}" >
<core:valueChangeListener type="beanPackage.SelectOneMenuListener" />
<core:selectItems value="#{databean.manyCheckBoxItems}" />
</html:selectOneMenu>
</p>
</html:form>
keulkeul.blogspot.com
valueChangeListenerTag.jsp
du projet Event
JSF - M. Baron - Page 530
La gestion des événements : changement de valeur
Exemple (suite) : abonnement via une « balise »
public class InputTextChangeListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) throws
AbortProcessingException {
System.out.println("InputText");
System.out.println(event.getOldValue());
System.out.println(event.getNewValue());
System.out.println(event.getComponent().getClass());
}
}
SelectOneMenuListener.java InputTextChangeListener.java
du projet Event du projet Event
keulkeul.blogspot.com
public class SelectOneMenuListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) throws
AbortProcessingException {
System.out.println("SelectOneMenu");
}
}
JSF - M. Baron - Page 531
La gestion des événements : changement de valeur
Exemple : abonnement via une « balise » et un « attribut »
<html:form> valueChangeListenerTagBis.jsp du
<p>
<html:outputText value="Veuillez saisir votre nom : " /> projet Event
<html:inputText onchange="submit()" value="#{mixdatabean.name}"
valueChangeListener="#{mixdatabean.inputChangement}" />
</p>
<p>
<html:outputText value="Choisissez votre périphérique : " />
<html:selectOneMenu onchange="submit()" value="#{mixdatabean.oneMenuValue}" >
<core:valueChangeListener type="beanPackage.DataBeanBis" />
<core:selectItems value="#{mixdatabean.manyCheckBoxItems}" />
</html:selectOneMenu>
</p>
public class DataBeanBis implements ValueChangeListener {
</html:form>
...
public void inputChangement(ValueChangeEvent event) {
System.out.println("InputText");
System.out.println(event.getOldValue());
keulkeul.blogspot.com
System.out.println(event.getNewValue());
System.out.println(event.getComponent().getClass());
}
DataBeanBis.java public void processValueChange(ValueChangeEvent event) throws
du projet Event AbortProcessingException {
System.out.println("SelectOneMenu");
}
}
JSF - M. Baron - Page 532
La gestion des événements : actions
Les événements associés aux actions sont déclenchés
quand des cliques sur des boutons ou des liens sont réalisés
L’événement transmis est de type ActionEvent
UIComponent getComponent() : renvoie la source
…
Préciser un écouteur de type ActionListener
par l’attribut actionListener (sa valeur est une méthode)
keulkeul.blogspot.com
par la balise actionListener (sa valeur est une classe)
Implémentation de l’interface ActionListener
void processAction(ActionEvent) : méthode qui traite l’action
JSF - M. Baron - Page 533
La gestion des événements : actions
Exemple : quatre saisons (abonnement via attribut)
<html:form>
<h1><html:outputText value="Quatre Saisons ... " /></h1> actionListenerAttribut.jsp
<html:panelGrid columns="2" >
du projet Event
<html:commandButton disabled="false" value="Hivers" id="Hivers"
binding="#{saisonbean.hivers}" actionListener="#{saisonbean.traiterHivers}"/>
<html:commandButton disabled="true" value="Printemps" id="Printemps"
binding="#{saisonbean.printemps}" actionListener="#{saisonbean.traiterPrintemps}"/>
<html:commandButton disabled="true" value="Eté" id="Ete"
binding="#{saisonbean.ete}" actionListener="#{saisonbean.traiterEteAutomne}"/>
<html:commandButton disabled="true" value="Automne" id="Automne"
binding="#{saisonbean.automne}" actionListener="#{saisonbean.traiterEteAutomne}" />
</html:panelGrid>
</html:form>
keulkeul.blogspot.com
JSF - M. Baron - Page 534
La gestion des événements : actions
Exemple (suite) : quatre saisons (abonnement via attribut)
public class SaisonBean {
public void traiterHivers(ActionEvent e) {
SaisonBean.java
hivers.setDisabled(true); du projet Event
printemps.setDisabled(false);
}
public void traiterPrintemps(ActionEvent e) {
printemps.setDisabled(true);
ete.setDisabled(false);
}
public void traiterEteAutomne(ActionEvent e) {
String id = e.getComponent().getId();
if (id.equals("Ete")) {
automne.setDisabled(false);
ete.setDisabled(true);
}
if (id.equals("Automne")) {
automne.setDisabled(true);
keulkeul.blogspot.com
hivers.setDisabled(false);
}
}
public HtmlCommandButton getAutomne() { return automne; }
public void setAutomne(HtmlCommandButton automne) { this.automne = automne; }
...
}
JSF - M. Baron - Page 535
La gestion des événements : actions
Exemple : des liens (abonnement par balise)
<html:form> actionListenerTag.jsp du projet
<h1><html:outputText value="Des liens ..." /></h1> Event
<html:commandLink value="Confirmer" id="confirmer">
<core:actionListener type="beanPackage.ActionBean" />
</html:commandLink>
<html:commandLink value="Annuler" id="annuler">
<core:actionListener type="beanPackage.ActionBean" />
</html:commandLink>
</html:form>
public class ActionBean implements ActionListener {
public void processAction(ActionEvent event) throws AbortProcessingException {
String id = event.getComponent().getId();
if (id.equals("confirmer")) {
System.out.println("Action Confirmation");
keulkeul.blogspot.com
if (id.equals("annuler")) {
System.out.println("Action Annulation");
}
} ActionBean.java du projet
} Event
JSF - M. Baron - Page 536
La gestion des événements : immediate
Rappelons la position de déclenchement des événements
dans le cycle de vie JSF
ValueChangeEvent après la phase de Process Validations
ActionEvent après la phase Invoke Application
Toutefois, il serait intéressant de pouvoir déclencher ces
événements juste après la phase Apply Request
Pourquoi, quel est l’intérêt de déclencher des événements
immédiatement ?
keulkeul.blogspot.com
Déclencher les événements d’un composant avant tous les événe-
ments des autres composants
« Court-circuiter » le processus de cycle de vie pour désactiver ou pas
la conversion et la validation des autres composants
JSF - M. Baron - Page 537
La gestion des événements : immediate
ActionEvent immédiat : les
ValueChangeEvent immédiat: ActionListener sont notifiés
Conversion et Validation puis les
ValueChangeListener sont notifiés Réponse Réponse
Complète Complète
Requête Restore Apply Process Process Process
Faces View Requests Events Validations Events
Réponse Réponse
Complète Complète
Réponse Update
Render Process Invoke Process
keulkeul.blogspot.com
Response Model
Faces Events Application Events
Values
Erreurs de Conversion
Erreurs de Conversion
et / ou de Validation JSF - M. Baron - Page 538
La gestion des événements : immediate
Pour déclencher des événements immédiatement, il faut
modifier la valeur de l’attribut immediate à true
Si un composant de saisie à un déclenchement immédiat
la conversion et la validation sont réalisées après la phase Apply
Request Values
les ValueChangeListener sont ensuite déclenchés
le cycle de vie continue sa progression (phase Process Validations)
Pour le stopper appel explicite à renderResponse() de FacesContext
Si un composant de command à un déclenchement immédiat
les ActionListener sont déclenchés
keulkeul.blogspot.com
le cycle de vie est court-circuité car appel implicite à RenderResponse
(FacesContext)
Il est à noter que le dernier cas a déjà été rencontré dans la
partie « Conversion des données » JSF - M. Baron - Page 539
La gestion des événements : immediate
Exemple : changement de localisation sans validation …
Ecran de démarrage
Si validation via le bouton de
soumission, le champ Téléphone
notifie d’une erreur de saisie
keulkeul.blogspot.com
Si changement de localisation
(composant SelectOneMenu)
avec l’attribut immediate à true,
la validation n’est pas effectuée JSF - M. Baron - Page 540
La gestion des événements : immediate
Exemple (suite) : changement de localisation sans validation
<core:view>
<core:loadBundle basename="EventMessages" var="bundle" />
<html:form>
<p>
<html:outputText value="#{bundle.PHONE_NUMBER_MESSAGE}"/>
<html:inputText id="priceId" value="#{selectimmediate.phonenumber}" >
<core:validateLength minimum="10" maximum="10"/>
</html:inputText><html:message for="priceId" />
</p>
<p>
<html:outputText value="#{bundle.COUNTRY_MESSAGE}"/>
<html:selectOneMenu onchange="submit()" immediate="true"
valueChangeListener="#{selectimmediate.countryChanged}"
value="#{selectimmediate.countryValue}" >
<core:selectItems value="#{selectimmediate.countryNames}" />
</html:selectOneMenu>
</p>
keulkeul.blogspot.com
<p>
<html:commandButton value="#{bundle.VALID_MESSAGE}"/>
</p>
</html:form> immediateAttribut.jsp du projet
</core:view> Event
JSF - M. Baron - Page 541
La gestion des événements : immediate
Exemple (suite) : changement de localisation sans validation
public class DataBeanSelectImmediate {
private static final String FRENCH_COUNTRY_NAME = "Français";
private static final String ENGLISH_COUNTRY_NAME = "English";
private SelectItem[] countryNames = new SelectItem[] {
new SelectItem(FRENCH_COUNTRY_NAME),
new SelectItem(ENGLISH_COUNTRY_NAME)
};
DataBeanSelectImmediate.java
public void countryChanged(ValueChangeEvent e) { du projet Event
System.out.println("DataBeanSelectImmediate.countryChanged()");
FacesContext current = FacesContext.getCurrentInstance();
if (FRENCH_COUNTRY_NAME.equals(e.getNewValue())) {
current.getViewRoot().setLocale(Locale.FRENCH);
} else {
current.getViewRoot().setLocale(Locale.ENGLISH);
}
current.renderResponse();
}
keulkeul.blogspot.com
EventMessages_fr.properties du projet Event
Court-circuite le cycle de vie par un
appel explicite Ne traite pas les PHONE_NUMBER_MESSAGE = Téléphone
autres composants JSF (pas de COUNTRY_MESSAGE = Pays
VALID_MESSAGE = Valider
conversion ni validation)
JSF - M. Baron - Page 542
La gestion des événements : cycle de vie
Avant et après chaque phase du cycle de vie JSF, des
événements de type PhaseEvent sont déclenchés
L’abonnement peut être utile lors de phases de déboguage
Le traitement des PhaseEvent est réalisé par un objet de
type PhaseListener
L’abonnement se fait via le fichier de configuration JSF en
déclarant le nom de la classe qui implémente PhaseListener
keulkeul.blogspot.com
Modification du fichier faces-config.xml
Ajouter la balise <lifecycle> et la sous balise <phase-listener>
Préciser le nom de la classe de type PhaseListener
JSF - M. Baron - Page 543
La gestion des événements : cycle de vie
Evénement PhaseEvent
getFacesContext() : retourne l’instance du FacesContext pour la
requête en cours de traitement
getPhaseId() : retourne l’ID de la phase du cycle de vie en cours de
traitement
Ecouteur PhaseListener
afterPhase(PhaseEvent) : appelée quand une phase du cycle de vie se
termine
beforePhase(PhaseEvent) : appelée avant le démarrage d’une phase
du cycle de vie
keulkeul.blogspot.com
PhaseId getPhaseId() : retourne un objet PhaseId permettant
d’identifier le listener à la phase
La classe PhaseId définit un ensemble de constantes permet-
tant d’identifier les différentes phases du cycleJSFde vie
- M. Baron - Page 544
La gestion des événements : cycle de vie
Exemple : traiter les événements de toutes les phases
<faces-config>
... faces-config.xml du projet Event
<lifecycle>
<phase-listener>beanPackage.LifeCycleListener</phase-listener>
</lifecycle>
</faces-config>
public class LifeCycleListener implements PhaseListener {
public void afterPhase(PhaseEvent phaseEvent) {
System.out.println("LifeCycleListener.afterPhase()" +
phaseEvent.getPhaseId());
}
public void beforePhase(PhaseEvent phaseEvent) {
System.out.println("LifeCycleListener.beforePhase()" +
phaseEvent.getPhaseId());
}
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
keulkeul.blogspot.com
LifeCycleListener.java du projet
Event
JSF - M. Baron - Page 545
Composants additionnels : Apache Tomahawk
La spécification JSF décrit un ensemble de composants qui
ont été implémentés entre autre par Apache MyFaces
Ces composants sont à l'utilisation très limités au niveau
interaction
Apache a donc fourni la bibliothèque Tomahawk dont
l'objectif est d'ajouter des fonctionnalités supplémentaires
http://myfaces.apache.org/tomahawk
Cette bibliothèque fournit
Des composants graphiques (extension à html)
Des composants fonctionnels (extension à core)
keulkeul.blogspot.com
Des validators A voir également « Tabago »
Et pleins d'autres choses qui est une autre bibliothèque
de composants
Adresse d’exemples http://myfaces.apache.org/tobago
http://www.irian.at/myfaces JSF - M. Baron - Page 546
Apache Tomahawk : composants graphiques
JSCook Menu
Tree « 2 »
Popup
keulkeul.blogspot.com
TabbedPane
Calendar
JSF - M. Baron - Page 547
Apache Tomahawk : composants graphiques (suite)
Extended Data Table
HtmlEditor
keulkeul.blogspot.com
Data Scroller
Tree Table
JSF - M. Baron - Page 548
Apache Tomahawk : composants graphiques (suite)
Panel Navigation 2 Schedule
Panel Navigation
keulkeul.blogspot.com
JSF - M. Baron - Page 549
Apache Tomahawk : Validators
Tomahawk fournit également des validators complémentaires
à ceux fournis par la spécification JSF
validateCreditCard
Pour valider un numéro de carte de crédit
Permet de choisir la marque (parmi amex, visa, mastercard, discover)
validateUrl
Pour valider une URL
validateEmail
Pour valider une adresse électronique
keulkeul.blogspot.com
validateRegExpr
Pour valider des expressions régulières
<html:inputText id="regExprValue" value="#{validateForm.regExpr}" required="true">
<t:validateRegExpr pattern='\d{5}'/>
</html:inputText>
JSF - M. Baron - Page 550
Apache Tomahawk : installation
Apache Tomahawk n’est ni plus ni moins qu’une librairie de
balise
Se rendre à l’adresse : http://myfaces.apache.org/download
Télécharger l’archive tomahawk-x.x.x-bin.zip
Décompresser dans le répertoire WEB-INF/lib de l’application
web
Importer les balises personnalisées de Tomahawk
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>
keulkeul.blogspot.com
Utiliser les balises de votre choix …
<html:inputText id="regExprValue" value="#{validateForm.regExpr}" required="true">
<t:validateRegExpr pattern='\d{5}'/>
</html:inputText>
JSF - M. Baron - Page 551
Composant personnalisé : principe
Pour bientôt …
Généralité sur la conception de composants personnalisés
Balises personnalisés, code du composant, rendu
Exemple : thermomètre étendu …
keulkeul.blogspot.com
JSF - M. Baron - Page 552
Bilan : cours JSF
Premières impressions d’un novice …
Une impression que c’est pas aussi « souple » que Struts
La disponibilité de la spécification de JSF et du tutorial sont vraiment
utiles (surtout pour comprendre le fonctionnement du cycle de vie)
Mes coups de coeur : l’approche par composants et la présence d’un
cycle de vie qui « tient la route »
Les outils, gratuits, sous Eclipse de bonne qualité sont peu nombreux
(utilisation du plugin Amateras : http://ameteras.sourceforge.jp)
Les choses non étudiés, prochainement …
Terminer : « créer son converter », « créer ses propres balises pour la
keulkeul.blogspot.com
convertion et la validation » puis « composant personnalisé »
Comparatif des outils pour gérer du JSF avec « plaisir » ;-)
« Proprifier » les sources des exemples et les diffuser
Les Facelets (système de template pour JSF) JSF - M. Baron - Page 553