Vous êtes sur la page 1sur 216

ROYAUME DU MAROC

Université Cadi Ayyad


Ecole Nationale des Sciences Appliqués
Département Génie Informatique, Réseaux & Télécoms
Safi
____________

JAVA EE

oujaoura@gmail.com Mustapha OUJAOURA


Chap: 1 JSF (JavaServer Faces)
• Introduction
• Architecture et Fonctionnement
• Cycle de vie
• Managed Bean (Bean géré)
• Navigation
• Internationalization (I18N)
• Composants
• Conversion
• Validation
• Evénements
• Composite Components
• Ajax
Introduction
3

¨ Framework de composant côté serveur pour la


création d'applications Web basées sur la
technologie Java
¨ Fournit un modèle de programmation bien défini et
diverses bibliothèques de balises
¨ Plusieurs implémentations:
¤ Mojarra (implémentation de référence)
¤ Apache MyFaces Project

¨ Supporté par les plus grandes entreprises et


organisations: IBM, Oracle, Apache, ...
Introduction
4

¨ Caractéristiques : Avec JSF, On peut avec un


minimum d'efforts:
¤ Créer une page web
¤ Déposer des composants sur une page Web en
ajoutant leur balises
¤ Lier un composant d'une page aux données côté
serveur
¤ Relier les événements générés par les composants
au code de l'application côté serveur
¤ Réutiliser et étendre un composant via la
personnalisation
Introduction
5

¨ Aux premiers jours de Java, les développeurs émettaient


directement du HTML à partir des servlets.
¨ Puis nous sommes passés des servlets à JSP.
¨ Et puis après, à des bibliothèques de marqueurs
personnalisés (JSTL).
¨ En réponse à certaines limitations de JSP, JSF (Java
Server Faces) a été créé.
¨ Inspiré de Swing, JSF consiste à porter des composants
graphiques vers le Web.
¨ JSF permet aux développeurs de penser en termes de
composants, d’événements, de beans gérés et de leurs
interactions plutôt qu’en termes de requêtes et de réponses.
¤ => Un cycle de vie un peu compliqué.
¨ JSF a pour but de faciliter et d’accélérer le développement
web (la réutilisation).
Introduction
6

¨ JSF 1.x se base sur JSP, par contre la version 2


se base sur les Facelets (pages xhtml).
¨ Facelets ? est une alternative openSource à
JSP ( n’est pas une JSR :Java Specification
Request).
¨ Fournit un modèle de programmation plus
simple que JSP.
¨ Dispose d’une bibliothèque de marqueurs (ui)
permettant d’écrire l’interface utilisateur et
reconnaît en partie les marqueurs JSTL (c:if,
c:forEach, c:catch et c:set).
Introduction
7

¨ JSF est un framework Web MVC qui simplifie la


construction d'interfaces utilisateur web pour les
applications distribuées en utilisant des composants
d'interface utilisateur réutilisables dans une page.
¨ JSF fournit une facilité pour connecter des composants
d'interface utilisateur à des sources de données et à des
gestionnaires d'événements côté serveur.
¨ La technologie JSF est basée sur l'architecture Model
View Controller (MVC) pour séparer la logique métier
de la présentation.
Pourquoi JSF ?
8
¨ Pour la plupart des applications, On peut remarque que :
¤ le code de la servlet contrôleur devient énorme et très difficile à lire.
¤ Il est nécessaire de modifier cette servlet à chaque création de page.
¨ JSF arrive pour anéantir ces problèmes.
Architecture JSF
9
¨ Une application JSF est similaire à toute autre application Web basée sur l’API
servlet de la technologie Java; Il s'exécute dans un conteneur de servlets Java, et
contient:
¤ Composants JavaBeans en tant que modèles contenant des fonctionnalités et des données
spécifiques à l'application.
¤ Une bibliothèque de balises personnalisée pour représenter des gestionnaires
d'événements et des validateurs.
¤ Une bibliothèque de balises personnalisée pour le rendu des composants de l'interface
utilisateur.
¤ Composants d'interface utilisateur représentés comme des objets avec état sur le serveur.
¤ Classes auxiliaires côté serveur.
¤ Validateurs, gestionnaires d'événements et gestionnaires de navigation.
¤ Fichier de ressources de configuration d'application pour la configuration des ressources
d'application.
¨ La création d'interfaces utilisateurs, le contrôle de la navigation dans les
appels synchrones ou asynchrones de la logique métier sont possibles parce
que JSF utilise le modèle de conception MVC(Modèle-Vue-Contrôleur).
Chaque partie est donc isolée des autres, ce qui permet de modifier
l'interface utilisateur sans conséquence sur la logique métier et vice versa.
Architecture JSF
10
Architecture JSF
11
Architecture JSF
12

¨ Basé sur l'architecture MVC (Model View Controller) pour


séparer la logique métier de la présentation:
View
(XHTML Files)

Controller
(Managed Beans)

Model
(Data Store)
¨ Couche basée directement sur l'API Servlet:
JavaServer Pages
JavaServer Faces Standard Tag Library
JavaServer Pages
Java Servlet
Services rendus par JSF
13

¨ Architecture MVC pour séparer l’interface utilisateur, la couche de


persistance et les processus métier, utilisant la notion d’événement,
¨ Conversion des données (tout est texte dans l’interface utilisateur),
¨ Validation des données (par exemple, des champs de formulaires),
¨ Automatisation de l’affichage des messages d’erreur en cas de
problèmes de conversion ou de validation,
¨ Internationalisation,
¨ Support d’Ajax sans programmation javascript (communication en
arrière-plan et mise à jour partielle de l’interface utilisateur),
¨ Fournit des composants standards simples pour l’interface utilisateur,
¨ Possible d’ajouter ses propres composants,
¨ Adaptable à d’autres langages de balise que HTML
Fonctionnement de JSF
14

¨ Le contrôleur est une servlet ( FacesServlet) qui intercepte


les requêtes HTTP liées aux applications JSF et qui organise
les traitements JSF (on n’a plus d’accès à cette servlet).
¨ La navigation et le traitement de la requête est décrit au
travers d'un fichier de configuration <faces-config.xml>
¨ Le modèle est représenté par les javaBeans: managed-
beans ( ou backing-beans).
¨ La vue est représentée par des composants Java sur le
serveur, transformées en pages HTML.
¨ JSF dispose d'un ensemble standard de composants
(graphiques ou sans apparences visuelles) et permet de créer
également facilement les vôtres (composants personnalisés).
Pour gérer cette arborescence, une page passe par un cycle
de vie complexe (initialisation, événements, affichage, etc.).
Fonctionnement de JSF
15
Cycle de vie JSF
16
¨ Le cycle de vie des applications JSF se compose de six phases :
¤ Restauration de la vue : JSF trouve la vue cible et lui applique les entrées de l'utilisateur. S'il s'agit de
la première visite, JSF crée la vue comme un composant UIViewRoot (racine de l'arborescence de
composants, qui constitue une page particulière). Pour les requêtes suivantes, il récupère
l'UIViewRoot précédemment sauvegardée pour traiter la requête HTTP courante.
¤ Application des valeurs de la requête : Les valeurs fournies avec la requête (champ de saisie, d'un
formulaire, valeurs des cookies ou à partir des en-têtes HTTP) sont appliquées aux différents
composants de la page. Seuls les composants UI (de la page) modifient leur état, non les objets
métiers qui forment le modèle.
¤ Validations : Lorsque tous les composants UI ont reçu leurs valeurs, JSF traverse l'arborescence de
composants et demande à chacun d'eux de s'assurer que la valeur qui leur a été soumise est correcte.
Si la conversion et la validation réussissent pour tous les composants, le cycle de vie passe à la phase
suivante. Sinon il passe à la phase de Rendu de la réponse avec les messages d'erreur de validation et
de conversion appropriés.
¤ Modification des valeurs du modèle : Lorsque toutes les valeurs des composants ont été affectées et
validées, les beans gérés qui leur sont associés peuvent être mis à jour.
¤ Appel de l'application : Nous pouvons maintenant exécuter la logique métier. Les actions qui ont été
déclenchées seront exécutées sur le bean géré. La navigation entre en jeu car c'est la valeur qu'elle
renvoie qui déterminera la réponse.
¤ Rendu de la réponse : Le but principal de cette phase consiste à renvoyer la réponse à l'utilisateur. Son
but secondaire est de sauvegarder l'état de la vue pour pouvoir la restaurer dans la phase de
restauration si l'utilisateur redemande la vue.
Cycle de vie JSF
17

¨ Les six phases montrent l'ordre dans lequel JSF traite une requête. La figure
montre les phases dans leur ordre d'exécution probable avec le traitement
des événements à chaque phase.
¨ Même cycle de traitement pour toute requête JSF:
Cycle de vie JSF
18
¨ JSF utilise la notion de vue (view) qui est composée d'une arborescence ordonnée de composants inclus
dans la page.
¨ Les requêtes sont prises en charge et gérées par le contrôleur d'une application JSF (en général une
servlet) qui va assurer la mise en oeuvre d'un cycle de vie des traitements en vue d'envoyer une réponse
au client.
¨ JSF propose pour chaque page un cycle de vie pour traiter la requête HTTP et générer la réponse. Ce
cycle de vie est composé de plusieurs étapes :
¤ Restore view ou Reconstruct Component Tree : cette première phase permet au serveur de recréer l'arborescence
des composants qui composent la page. Cette arborescence est stockée dans un objet de type FacesContext et sera
utilisée tout au long du traitement de la requête.
¤ Apply Request Value : dans cette étape, les valeurs des données sont extraites de la requête HTTP pour chaque
composant et sont stockées dans leur composant respectif dans le FaceContext. Durant cette phase des opérations de
conversions sont réalisées pour permettre de transformer les valeurs stockées sous forme de chaînes de caractères
dans la requête http en un type utilisé pour le stockage des données.
¤ Perform validations : une fois les données extraites et converties, il est possible de procéder à leur validation en
appliquant les validators enregistrés auprès de chaque composant. Les éventuelles erreurs de conversions sont
stockées dans le FaceContext. Dans ce cas, l'étape suivante est directement « Render Response » pour permettre de
réafficher la page avec les valeurs saisies et afficher les erreurs
¤ Synchronize Model ou update model values : cette étape permet de stocker dans les composants du FaceContext
leurs valeurs locales validées respectives. Les éventuelles erreurs de conversions sont stockées dans le FaceContext.
Dans ce cas, l'étape suivante est directement « Render Response » pour permettre de réafficher la page avec les
valeurs saisies et d' afficher les erreurs
¤ Invoke Application Logic : dans cette étape, le ou les événements émis dans la page sont traités. Cette phase doit
permettre de déterminer la page résultat qui sera renvoyée dans la réponse en utilisant les règles de navigation
définies dans l'application. L'arborescence des composants de cette page est créée.
¤ Render Response : cette étape se charge de créer le rendu de la page de la réponse.
Cycle de vie JSF
19
Phase 1: Restaurer la vue
20
Phase 1: Restaurer la vue
21

¨ JSF commence la phase de restauration dès qu'un lien ou


un bouton est cliqué et que JSF reçoit une requête.
¨ Au cours de cette phase, JSF construit la vue, les
gestionnaires d'événements et les validateurs des
composants d'interface utilisateur, et enregistre la vue dans
l'instance FacesContext.
¨ L'instance de FacesContext contient maintenant toutes les
informations requises pour traiter une requête.
¨ La vue qui correspond à la page qui contient le formulaire
est restaurée (phase « Restore View »),
¨ Tous les composants reçoivent la valeur qu’ils avaient avant
les nouvelles saisies de l’utilisateur.
Phase 2 : Récupération des
22
valeurs
Phase 2 : Récupération des
23
valeurs
¨ Une fois que l'arborescence des composants a été créée /
restaurée, chaque composant de l'arborescence des composants
extrait sa nouvelle valeur des paramètres de la requête.
¨ Le composant stocke cette valeur et la conserve dans une
variable.
¨ En fait, chaque composant de la vue récupère ses propres
paramètres de la requête HTTP.
¨ Si la conversion échoue, un message d'erreur est généré et mis
en file d'attente sur FacesContext.
¨ Ce message sera affiché pendant la phase de réponse de
rendu, ainsi que toutes les erreurs de validation.
¨ Si l’une des méthodes decode/ écouteur d'événements ont
appelés renderResponse sur l'instance actuelle de FacesContext,
le JSF passe à la phase de rendu de réponse.
Phase 3: Validation
24
Phase 3: Validation
25

¨ Au cours de cette phase, le JSF traite tous les validateurs


enregistrés sur l'arbre des composants.
¨ Toutes les validations des données traitées à l’étape
précédentes sont exécutées,
¨ Il examine les règles d'attribut de composant pour la validation
et compare ces règles à la valeur locale stockée pour le
composant.
¨ Les données sont converties dans les bons types Java,
¨ Si la valeur locale n'est pas valide, JSF ajoute un message
d'erreur à l'instance FacesContext et le cycle de vie avance à la
phase de rendu de réponse et affiche à nouveau la même
page avec le message d'erreur.
¨ Si une validation échoue, la main est donnée à la phase de
rendu de la réponse.
Phase 4: Mise à jour des
26
modèles
Phase 4: Mise à jour des
27
modèles
¨ Une fois que JSF vérifie que les données sont valides, il parcourt
l'arborescence des composants et définit les propriétés d'objet
côté serveur correspondantes aux valeurs locales des
composants.
¨ JSF met à jour les propriétés du bean correspondant à l'attribut
valeur du composant d'entrée.
¨ Si l’une des méthodes updateModels a appelé renderResponse
sur l'instance actuelle de FacesContext, le JSF passe à la phase
de rendu de réponse.
¨ Les données validées sont mises à jour dans les variables
d’instance des Java beans associés aux composants de l’arbre
des composants.
¨ La méthode processUpdates() de UIComponent est appelée
récursivement sur l'arbre des composants. Sa responsabilité
consiste à mettre à jour les modèles.
Phase 5: Invocation de
28
l'application
Phase 5: Invocation de
29
l'application
¨ Au cours de cette phase, le JSF gère tous les événements
au niveau de l'application, tels que la soumission d'un
formulaire / redirection et navigation vers une autre page.
¨ Les actions associées aux boutons ou aux liens sont
exécutées,
¨ Le plus souvent le lancement des processus métier se fait
par ces actions,
¨ La valeur de retour de ces actions va déterminer la
prochaine page à afficher (navigation),
¨ La méthode processApplication() de UIComponent, consiste
à diffuser certains événements de la queue vers les
écouteurs d'événements associés (listeners).
Phase 6: Rendu de réponse
30
Phase 6: Rendu de réponse
31

¨ Au cours de cette phase, le JSF demande au serveur d’application


(conteneur) de rendre la page si l'application utilise des pages JSP.
¨ Pour la requête initiale (soumise pour la 1ere fois), les composants
représentés sur la page seront ajoutés à l'arborescence des composants
lorsque le conteneur JSP exécute la page.
¨ Si ce n'est pas une requête initiale, l'arborescence des composants est
déjà construite de sorte que les composants ne doivent pas être ajoutés
à nouveau.
¨ Dans les deux cas, les composants se rendront eux-mêmes lorsque le
conteneur / serveur d'applications JSP parcourra les balises dans la
page.
¨ Une fois le contenu de la vue rendu, l'état de la réponse est enregistré
pour que les requêtes suivantes puissent y accéder et il est disponible
pour la phase de restauration de la vue.
¨ La page déterminée par la navigation est encodée en HTML et envoyée
vers le client HTTP.
Cycle de vie JSF : Récapitulation
32

¨ À la réception de la requête, la hiérarchie des composants


(arbre de vue) de la page demandée est créée.
¨ Les valeurs de la requête sont récupérées et stockées dans
les composants de l'arbre de vue.
¨ La méthode validate() est appelée pour tous les validators
stockés dans l'arbre de vue créé à l'étape précédente.
¨ Les valeurs contenues dans les composants sont ensuite
recopiées dans les objets métiers.
¨ L'événement de type <f:form> ou <h:command...>
correspondant à la demande d'une nouvelle page est traitée.
¨ La hiérarchie de composants s'occupe de créer toutes les
balises standard nécessaires pour représenter la réponse au
format désiré.
Structure d'une application JSF
33
¨ Les applications utilisant JSF sont des applications web qui doivent respecter les
spécifications de J2EE. Elles doivent alors avoir la structure définie par J2EE pour
toutes les applications web :
/
/WEB-INF
/WEB-INF/web.xml ; faces-config.xml
/WEB-INF/lib
/WEB-INF/classes
¨ Chaque implémentation nécessite un certain nombre de bibliothèques tierces pour son
bon fonctionnement.
¨ Les fichiers nécessaires dépendent de l'implémentation utilisée.
¨ Ces bibliothèques peuvent être mises à disposition de l'application selon plusieurs
modes :
¤ incorporées dans le package de l'application dans le répertoire /WEB-INF/lib
¤ incluses dans le répertoire des bibliothèques partagées par les applications web des
conteneurs web s'ils proposent une telle fonctionnalité. Par exemple avec Tomcat, il est
possible de copier ces bibliothèques dans le répertoire shared /lib.
¨ L'avantage de la première solution est de faciliter la portabilité de l'application sur
différents conteneur web mais elle duplique ces fichiers si plusieurs applications
utilisent JSF.
Configuration d’une application
34
JSF
¨ Toute application utilisant JSF doit posséder au moins
deux fichiers de configuration qui vont contenir les
informations nécessaires à sa bonne exécution.
¤ Le premier fichier est le descripteur de toute application web
J2EE : le fichier web.xml contenu dans le répertoire WEB-INF.
n Depuis la sortie de JSF 2.0, si on utilise un conteneur de Servlet 3.x,
la servlet FacesServlet est automatiquement mappé, il n’est donc
pas nécessaire de modifier la configuration de web.xml. (url
comence par : faces/* )
¤ Le second fichier est un fichier de configuration au format
XML, particulier au paramétrage de JSF et nommé par défaut
faces-config.xml.
Configuration d’une application
35
JSF : Le fichier web.xml
¨ Le fichier web.xml doit contenir au minimum certaines informations notamment, la
servlet servant de contrôleur, le mapping des URLs pour cette servlet et des
paramètres pour configurer JSF.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<display-name>exemplesJSF</display-name>
<description>Application de test avec JSF</description>
<context-param> <!– Mode d’échange de l’état de la vue (arbre de composants):client/server -->
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<servlet> <!-- Servlet servant de controleur -->
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping> <!-- Le mapping de la servlet -->
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
Configuration d’une application
36
JSF : Le fichier web.xml
¨ Le tag <servlet> permet de définir une servlet et plus particulièrement dans ce cas de
préciser la servlet qui sera utilisée comme contrôleur dans l'application. Le plus simple est
d'utiliser la servlet fournie avec l'implémentation de référence
javax.faces.webapp.FacesServlet.
¨ Le tag <load-on-startup> avec comme valeur 1 permet de demander le chargement de cette
servlet au lancement de l'application. Les URL utilisées pour des pages mettant en oeuvre JSF
doivent obligatoirement passer par cette servlet.
¨ Le tag <servlet-mapping> permet de préciser le mapping des URLs qui seront traitées par la
servlet. Ce mapping peut prendre deux formes :
¤ mapping par rapport à une extension : exemple <url-pattern>*.faces</url-pattern>.
¤ mapping par rapport à un préfixe : exemple <url-pattern>/faces/*</url-pattern>.
¨ Le paramètre de contexte javax.faces.STATE_SAVING_METHOD précise le mode d'échange
de l'état de l'arbre des composants de la page. Deux valeurs sont possibles : client, server
¤ La principale différence technique réside dans le fait que le paramètre client stocke l’état de vue dans son
intégralité comme valeur du champ d’entrée masqué javax.faces.ViewState dans la sortie HTML générée et que le
paramètre server le stocke dans la session avec un ID unique qui est référencé comme valeur du champ d'entrée
masqué javax.faces.ViewState.
¤ Par conséquent, le paramètre client augmente l'utilisation de la bande passante du réseau, mais diminue l'utilisation
de la mémoire du serveur, tandis que le paramètre server fait l'inverse. le paramètre client présente toutefois un
avantage fonctionnel supplémentaire: elle empêche les exceptions ViewExpiredExceptions lorsque la session a expiré
ou lorsque le client ouvre trop de vues.
¨ Le tag <welcome-file-list> permet de préciser que cette page est la page par défaut de
l'application.
Configuration d’une application
37
JSF : Le fichier faces-config.xml
¨ Le plus simple est de placer ce fichier dans le répertoire WEB-INF de l'application
Web.
¨ Il est aussi possible de préciser son emplacement dans un paramètre de contexte
nommé javax.faces.application.CONFIG_FILES dans le fichier web.xml. Il est
possible par ce biais de découper le fichier de configuration en plusieurs morceaux.
Ceci est particulièrement intéressant pour de grosses applications car un seul fichier
de configuration peut dans ce cas devenir très gros. Il suffit de préciser chacun des
fichiers séparés par une virgule dans le tag <param-value>.
...
<context-param>
<param-name>javax.faces.application.CONFIG_FILES</param-name>
<param-value>
/WEB-INF/my-faces-config.xml, /WEB-INF/navigation-faces.xml, /WEB-INF/beans-faces.xml
</param-value>
</context-param>
...

¨ Le fichier faces-config.xml au format XML permet de définir et de fournir des valeurs


d'initialisation pour des ressources nécessaires à l'application utilisant JSF.
¨ Le tag racine du document XML est le tag <face-config>. Ce tag peut avoir 0 ou
plusieurs tags fils parmis les tags suivants:
Configuration d’une application
38
JSF : Le fichier faces-config.xml
Tag Rôle
application permet de préciser ou de remplacer des éléments de l'application
permet de remplacer des fabriques par des fabriques personnalisées de
factory certaines ressources(FacesContextFactory, LifeCycleFactory,
RenderKitFactory, …)
component définit un composant graphique personnalisé
définit un convertisseur pour encoder/décoder les valeurs des
converter
composants graphiques (conversion de String en Object et vice versa)
managed- définit un objet utilisé par un composant qui est automatiquement créé,
bean initialisé et stocké dans une portée précisée
navigation- définit les règles qui permettent de déterminer l'enchaînement des
rule traitements de l'application
render-kit définit un kit pour le rendu des composants graphiques
définit un validateur personnalisé de données saisies dans un
validator
composant graphique
Pour plus d’informations, voir : http://horstmann.com/corejsf/faces-
Configuration d’une application
39
JSF : Le fichier faces-config.xml
¨ Le tag <application> permet de préciser des informations sur les
entités utilisées par l'internationalisation et/ou de remplacer des
éléments de l'application.
¤ Les éléments à remplacer peuvent être : ActionListener, NavigationHandler,
ViewHandler, PropertyResolver, VariableResolver. Ceci n'est utile que si la
version fournie dans l'implémentation ne correspond pas aux besoins et
doit être personnalisée par l'écriture d'une classe dédiée.
¤ Le tag fils <message-bundle> permet de préciser le nom de base des
fichiers de ressources utiles à l'internationalisation.
¤ Le tag <locale-config> permet de préciser les locales qui sont supportées
par l'application. Il faut utiliser autant de tags fils <supported-locale>
que de locales supportées. Le tag fil <default-locale> permet de préciser
...
la locale par défaut.
<application>
<message-bundle>resources.Messages</message-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
</locale-config>
</application>
...
Hello JSF : Faces Servlet
40

¨ Une application JSF est comme toutes les applications Web Java
déjà développées
¤ Mais en utilisant la bibliothèque JSF
¨ Donc, la première chose à faire pour utiliser JSF dans des projets est
de:
¤ Choisir une implémentation JSF
¤ Télécharger les bibliothèques correspondantes (pour certains serveurs)
¨ Pour utiliser JSF au-dessus de l'API Servlet, on doit déclarer une
servlet spécial fourni par le Framework, dont on a plus accès:
<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>*.xhtml</url-pattern>
</servlet-mapping>

¨ Avec cette déclaration, toutes les requêtes correspondant au modèle


d'URL seront traitées par JSF via la FacesServlet.
Hello JSF : vue
41

¨ On veut une simple page affichant un message de bienvenue avec la date


et l'heure actuelle.
¨ Tout d'abord, on crée une page hello.xhtml:
<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">

<h:head>
<title>Hello World From JSF</title>
</h:head>
<body>
<!-- Afficher le message "Hello World" -->
#{hello.SayHello()}
</body>
</html>

¤ JSF 2.0 utilise un moteur de modèle appelé Facelets au lieu des pages JSP
classiques
¤ Mais on peut toujours les utiliser si on le veut…
¨ Ce qu’on doit comprendre pour le moment à propos de Facelets:
¤ L'espace de noms avec le préfixe h est une taglib JSF
¤ Les éléments avec ce préfixe sont des composants JSF
Hello JSF : contrôleur
42

¨ Maintenant, on a besoin d’un composant (contrôleur?) Avec lequel la vue


pourrait demander le message de bienvenue
¨ Ce type de composant s'appelle Managed Bean (bean géré )
¨ Les beans gérés (Managed Bean) sont des composants gérés par la
technologie JavaServer Faces.
¨ Les composants d'une page peuvent leur être associés
¨ Pour l’exemple, on a juste besoin d'un bean géré simple comme suit:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.faces.bean.ManagedBean;

@ManagedBean
public class Hello {

private final static DateFormat dateFormat = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss");


private final String message = "Hello World From JSF";

public String SayHello() {


return message + " " + dateFormat.format(new Date());
}
}
Hello JSF : Interaction vue /
43
contrôleur
¨ Pour obtenir le message à partir de la vue, il suffit d'utiliser une
Expression Language (EL): #{hello.SayHello()}
¨ Attention, les Expression Language en JSF sont précédés du # et
non pas du $ .
La Syntaxe des Facelets
44

¨ Les facelets sont basés sur XHTML


¨ Elles remplacent toutes les pages JSP par des pages XHTML
¨ Plus de balises <%%>
¨ Expression Language directement traité dans XHTML
¨ Les taglibs sont déclarés avec un espace de noms XML :
xmlns:tag_name="uri"

¨ Espace de noms XML pour les balises HTML dans JSF:


xmlns:h="http://java.sun.com/jsf/html"

¨ Les balises JSTL sont toujours supportés


¤ Ils sont capables de gérer des tests, des boucles, etc.
n <c:if test="…">
n <c:forEach items="…" var="…">
n A condition d’inclure l’espace de noms XML correspondant qui est :
xmlns:c="http://java.sun.com/jsp/jstl/core"
La Syntaxe des Facelets
45
¨ JSF ajoute des déclarations supplémentaires à la balise <html>
¤ <html xmlns = "http://www.w3.org/1999/xhtml"
¤ xmlns: h = "http://xmlns.jcp.org/jsf/html">
¨ JSF remplace l’en-tête et le corps par des tags JSF
¤ - l’en-tête à h: head
¤ - le corps à h: body
¨ JSF utilise ses propres balises pour tous les éléments du formulaire
¤ form à h: form
¤ input type="text" à h:inputText
¤ input type="submit" à h:commandButton
¤ Etc …
¨ En XHTML, utiliser des minuscules pour les noms de balises, noms d'attributs et valeurs
prédéfinies
¨ En XHTML, on doit toujours utiliser des guillemets simples ou doubles.
¨ Toutes les balises sont des conteneurs. Les balises de fin sont toujours obligatoires.
¤ <p> ... </ p>, <li> ... </ li>
¨ S'il n'y a pas de contenu dans le corps de la balise, les balises de début / fin peuvent être
fusionnées
¤ <br> </ br> à <br/>
La Syntaxe des Facelets
46

¨ Structure de base des pages JSF :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head>

</h:head>
<h:body>

<h:form>

</h:form>

</h:body>
</html>

¨ Pour JSF 2.0 et 2.1: noter que http://java.sun.com a été


remplacé par http://xmlns.jcp.org , mais l’ancien nom
fonctionne toujours pour la compatibilité ascendante.
Ressources pour JSF
47

¨ Dans JSF 2.0, tous les fichiers de


ressources Web comme css, images ou
JavaScript, doivent être placés dans le
dossier «resources», sous la racine de
l’application Web (même niveau de
dossier que «WEB-INF»).
¨ Le sous-dossier du répertoire
«resources» est considéré comme
«bibliothèque» ou «thème de projet»,
plus tard on peut les référencer avec
l'attribut library.
¨ Ce nouveau mécanisme de gestion des
ressources JSF est vraiment utile, il
permet aux développeurs de modifier
facilement les ressources Web par
«thème / bibliothèque» ou
«versionnage».
Ressources pour JSF
48

¨ En utilisant le tag <h:outputStylesheet />, on peut charger les


feuilles de style :
¤ <h:outputStylesheet library = "css" name = "styles.css" />
¨ En utilisant le tag <h:graphicImage/>, on peut introduire une
image dans la page JSF (ne pas oublier de prévoir le
répertoire WebContent/resources/img et l'image).
¤ <h:graphicImage library="img" name="image.jpg"/>
¨ En utilisant le tag <h:outputScript />, on peut utiliser les les
scripts javascript:
¤ <h:outputScript library =" js" name = "hello.js" />
¨ On peut utiliser d’autres librairies :
<h:outputStylesheet library="webjars" name="bootstrap/3.3.7/css/bootstrap.min-jsf.css" />
<h:outputScript library="webjars" name="jquery/1.11.1/jquery.js" />
<h:outputScript library="webjars" name="bootstrap/3.3.7/js/bootstrap.js" />
CSS pour JSF
49

¨ Charger les feuilles de style


¤ HTML et JSF
n <link href = "css / styles.css" rel = "stylesheet" type = "text / css" />
¤ JSF seulement
n <h: outputStylesheet name = "styles.css" library = "css" />
¨ Appliquer des styles (commençant par “.”)
¤ Eléments HTML: <tag class = "name">
¤ Eléments JSF: <h: tag styleClass = "name">
¨ sélecteurs
¤ h1 {…}
n S'applique à tous les éléments h1
¤ .foo {…}
n S'applique à <tag class = "foo"> ou <h: tag styleClass = "foo">
¤ div table.bar td {…}
n S'applique aux éléments td à l'intérieur de <table class = "bar"> qui sont à l'intérieur
des éléments divs
Les Bean
50

¨ Les beans sont largement utilisés dans une application


JSF notamment pour permettre l'échange de données
entre les différentes entités et le traitement des
événements.
¨ Les beans sont des classes qui respectent une
spécification particulière notamment la présence :
¤ de getters et de setters qui respectent une convention de
nommage particulière pour les attributs
¤ un constructeur par défaut sans arguments
Bean géré (Managed Bean)
51

¨ Managed Bean est une classe régulière Java Bean enregistrée


avec JSF. En d'autres termes, Managed Beans est un java bean
géré par le framework JSF.
¨ Managed Bean contient les méthodes getter et setter, la logique
métier ou même un bean de support (un bean contient toute les
valeurs du formulaire HTML).
¨ Les beans gérés fonctionnent comme modèle pour le composant
d'interface utilisateur.
¤ Managed Bean peut être consulté à partir de la page JSF.
¨ Dans JSF 1.2, un bean géré doit être enregistrer dans un fichier
de configuration JSF tel que faces-config.xml.
¨ À partir de JSF 2.0, les beans gérés peuvent être facilement
enregistrés à l'aide d'annotations. Cette approche permet de
conserver les beans et leur enregistrement en un seul endroit, ce
qui facilite leur gestion.
Bean géré (Managed Bean)
52

¨ Les beans gérés sont des classes Java prises en charge par la
FacesServlet.
¨ Les composants de l’interface utilisateur sont liés aux propriétés du
bean et peuvent invoquer des méthodes d’action.
¨ ManagedBeans sont le lien entre les objets Java et les pages Web
¨ Pour utiliser un JavaBean dans des pages Web
¤ On le déclare et on l’enregistre en tant que ManagedBean :
n À l'intérieur du fichier faces-config.xml
n Avec l'annotation @ManagedBean
¤ Puis, On l’utilise dans des pages JSP ou Facelets
JavaBean @ManagedBean ou bien Page.jsp
faces-config.xml
<managed-bean>
...
</managed-bean>
Bean géré (Managed Bean)
53

¨ Un bean géré, est une classe, qui doit :


¤ Etre publique et non finale ni abstraite.
¤ Avoir un constructeur public sans paramètre qui sera utilisé par
le conteneur pour créer les instances.
¤ Avoir des attributs privés liés à des composants par des getters
et des setters publics.
Bean géré (Managed Bean)
54

¨ Les beans managés sont des javabeans dont le cycle de vie va être contrôlé
par le framework JSF en fonction des besoins et du paramétrage fourni dans
le fichier de configuration.
¨ Dans le fichier de configuration, chacun de ces beans doit être déclaré avec
un tag <managed-bean>. Ce tag possède trois tags fils obligatoires :
¤ <managed-bean-name> : le nom attribué au bean (celui qui sera utilisé lors de
son utilisation)
¤ <managed-bean-class> : le type pleinement qualifié de la classe du bean
¤ <managed-bean-scope> : précise la portée dans laquelle le bean sera stocké et
donc utilisable
¨ La portée peut prendre les valeurs suivantes :
¤ request : cette portée est limitée entre l'émission de la requête et l'envoi de la
réponse. Les données stockées dans cette portée sont utilisables lors d'un transfert
vers une autre page (forward). Elles sont perdues lors d'une redirection (redirect).
¤ session : cette portée permet la circulation de données entre plusieurs échanges
avec un même client
¤ application : cette portée permet l'accès à des données pour toutes les pages
d'une même application quelque soit l'utilisateur
Bean géré (Managed Bean)
55

¨ Déclaration du bean géré:


¤ Soit dans faces-config.xml :
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
<managed-bean>
<managed-bean-name>beanName</managed-bean-name>
<managed-bean-class>
nom complet de la classe java du bean
</managed-bean-class>
<managed-bean-scope>
(application|session|request|view|none)
</managed-bean-scope>
</managed-bean>
</faces-config>

¤ Soit par l’annotation @javax.faces.bean.ManagedBean


n À partir de JSF 2.2+, on devrait utiliser des annotations CDI (@Named) plutôt
que @ManagedBean pour rendre ces classes de contrôleurs injectables.
Bean géré (Managed Bean)
56

¨ Déclaration du bean géré :


¤ Dans le fichier de configuration WEB-INF/faces-config.xml :
n Un simple JavaBean :
public class User {
private String name;
// Getters and Setters
}

n Qu’on déclare dans faces-config.xml :


<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.example.model.User</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

¤ Dans le code par l’annotation


@javax.faces.bean.ManagedBean :
@ManagedBean(name=”userBeanName", eager=true)
public class User {
private String name;
// Getters and Setters
}
Bean géré (Managed Bean)
57
¨ L’annotation @ManagedBean marque un bean comme étant un bean géré avec le nom
spécifié dans l'attribut name. Si l'attribut name n'est pas spécifié, le nom du bean géré sera
par défaut le nom de la classe.
¨ Un autre attribut important est eager. Si eager = "true", le bean géré est créé avant la
première demande (requete), sinon une initialisation retardée "lazy" est utilisée, dans laquelle
le bean sera créé uniquement lorsqu'il est demandé.
¨ Les annotations Portée définissent la portée dans laquelle le bean géré sera placé. Si
l'étendue n'est pas spécifiée, alors le bean demandera par défaut l'étendue :
¤ @RequestScoped : Le Bean vit aussi longtemps que la requête-réponse HTTP vit. Il est créé sur une
requête HTTP et détruit lorsque la réponse HTTP associée à la requête HTTP est terminée.
¤ @NoneScoped : Le Bean vit aussi longtemps qu'une seule évaluation EL. Il est créé lors d'une
évaluation EL et est détruit immédiatement après l'évaluation EL.
¤ @ViewScoped : Le bean vit tant que l'utilisateur interagit avec la même vue JSF dans la fenêtre /
l'onglet du navigateur. Il est créé sur une requête HTTP et est détruit une fois que l'utilisateur a
postbacké sur une vue différente.
¤ @SessionScoped : Le Bean vit aussi longtemps que la session HTTP vit. Il est créé lors de la première
requête HTTP impliquant ce bean dans la session et est détruit lorsque la session HTTP est invalidée.
¤ @ApplicationScoped: Bean vit aussi longtemps que l'application Web vit. Il est créé lors de la
première requête HTTP impliquant ce bean dans l'application (ou lorsque l'application Web démarre
et que l'attribut eager = true est défini dans @ManagedBean) et est détruit à la fermeture de
l'application Web.
Bean géré (Managed Bean)
58

¨ Initialisation des propriétés du bean géré :


¤ Dans faces-config.xml :
n Par des valeurs :
<managed-bean> ... </managed-bean>
<managed-property>
<property-name>name</property-name>
<value>Mohamed</value>
</managed-property>
n Par un autre bean géré :
<managed-bean>
<managed-bean-name>message</managed-bean-name>
<managed-bean-class>com.example.model.MessageBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.example.model.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>messageBean</property-name>
<property-class>com.example.model.MessageBean</property-class>
<value>#{message}</value>
</managed-property>
</managed-bean>
Bean géré (Managed Bean)
59

¨ Initialisation des propriétés du bean géré :


¤ Par l’annotation @ManagedBean en utilisant @ManagedProperty :
package com.example.model;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
@ManagedBean @SessionScoped
public class HelloBean implements Serializable{
@ManagedProperty(name = "messageBean" , value="#{message}")
private MessageBean messageBean;
// Getters and Setters
}

¨ Il faut être prudent lors de l’initialisation d’un ManagedBean avec un autre!


ManagedBean enregistré … ne peut se référer qu'à d'autres ManagedBeans avec les
avec la portée… portées suivantes
none none
request none, request, session, application
session none, session, application
application none, application
Bean géré (Managed Bean)
60

¨ Il est toujours nécessaire dans la partie présentation d'obtenir la valeur d'une


donnée d'un bean pour par exemple l'afficher.
¨ JSF propose une syntaxe basée sur des expressions qui facilitent l'utilisation
des valeurs d'un bean.
¨ Utilisation des beans gérés dans des pages web :
¤ Lier une valeur simple
<h:outputText value="#{bean.property}" />
import javax.faces.bean.ManagedBean;
@ManagedBean
public class Bean {
private String property;
// Getters and Setters
}
¤ Lier un composant JSF dans une classe java (backing bean)
<h:outputText binding="#{bean.component}" />
import javax.faces.component.html.HtmlOutputText;
public class Bean {
private HtmlOutputText component;
// getter and setter
}
¨ JSF définit un ensemble de variables prédéfinies et utilisables dans les expressions de
liaison de données (donné par le tableau suivant):
Variable Rôle
collection de type Map encapsulant les éléments définis dans les
header Bean géré (Managed Bean)
paramètres de l'en-tête de la requête http (seule la première valeur est
renvoyée)
61 une collection de type Map encapsulant les éléments définis dans les
header-values paramètres de l'en-tête de la requête http (toutes les valeurs sont
renvoyées sous la forme d'un tableau)
une collection de type Map encapsulant les éléments définis dans les
param
paramètres de la requête http (seule la première valeur est renvoyée)
collection de type Map encapsulant les éléments définis dans les
param-values paramètres de la requête http (toutes les valeurs sont renvoyées sous la
forme d'un tableau)
cookies collection de type Map encapsulant les éléments définis dans les cookies
une collection de type Map encapsulant les éléments définis dans les
initParam
paramètres d'initialisation de l'application
collection de type Map encapsulant les éléments définis dans la portée
requestScope
request
collection de type Map encapsulant les éléments définis dans la portée
sessionScope
session
une collection de type Map encapsulant les éléments définis dans la
applicationScope
portée application
facesContext une instance de la classe FacesContext
View une instance de la classe UIViewRoot qui encapsule la vue
Bean géré (Managed Bean)
62

¨ Lorsque qu'une variable est utilisée dans une expression, JSF recherche dans
la liste des variables prédéfinies, puis recherche une instance dans la portée
request, puis dans la portée session et enfin dans la portée application. Si
aucune instance n'est trouvée, alors JSF crée une nouvelle instance en tenant
compte des informations du fichier de configuration. Cette instanciation est
réalisée par un objet de type VariableResolver de l'application.
¨ Il est possible de concaténer les résultats des évaluations de plusieurs
expressions simplement en les plaçant les uns à la suite des autres:
<h:outputText value="#{messages.salutation}, #{utilisateur.nom}!"/>

¨ Il est parfois nécessaire d'évaluer une expression dans le code des objets
métiers pour obtenir sa valeur.
FacesContext context = FacesContext.getCurrentInstance();
ValueBinding binding = context.getApplication().createValueBinding("#{utilisateur.nom}");
String nom = (String) binding.getValue(context);

¨ Comme tous les composants sont stockés dans le FaceContext, il est possible
d'accéder à cet objet pour obtenir les informations désirées. Il est d'abord
nécessaire d'obtenir l'instance courante de l'objet FaceContext en utilisant la
méthode statique getCurrentInstance() :
FacesContext context = FacesContext.getCurrentInstance();
Bean géré (Backing beans)
63

¨ Le backing bean est utile pour la validation, la conversion, la gestion des


événements des composants de l'interface utilisateur. En d'autres termes, les
propriétés du backing bean sont liées aux composants de l'interface dans la
page JSF.
¨ Les beans de type backing bean sont spécialement utilisés avec JSF pour
encapsuler tout ou partie des composants de l'interface utilisateur d'une page
et ainsi faciliter leur accès notamment lors des traitements.
¨ Ces beans sont particulièrement utiles durant des traitements réalisés lors de
validations ou de gestion d'événements car ils permettent un accès aux
composants dont ils possèdent une référence.

<h:outputText value="Nom : " />


<h:inputText value="#{loginBean.nom}" binding="#{loginBean.composantNom}" />
<br/>
<h:outputText value="Hello #{loginBean.nom}" />
Bean géré (Backing beans)
64

import javax.faces.bean.ManagedBean;
import javax.faces.component.UIInput;
@ManagedBean
public class LoginBean {
private UIInput composantNom;
private String nom;
public UIInput getComposantNom() {
return composantNom;
}
public void setComposantNom(UIInput input) {
composantNom = input;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
}
Bean géré (Managed Bean)
65

¨ Il est recommandé de placer les beans gérés dans un fichier XML


distinct, car le faces-config.xml est utilisé pour définir les
configurations au niveau de l'application.
¨ On doit donc créer un nouveau fichier XML et y placer le détail des
beans gérés et déclarer le fichier XML dans le paramètre
d'initialisation javax.faces.CONFIG_FILES, qui se trouve dans le
fichier WEB-INF / web.xml.
...
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>WEB-INF/manage-beans.xml</param-value>
</context-param>
...

(Fichier WEB-INF/manage-beans.xml)
...
<managed-bean>
<managed-bean-name>helloBean</managed-bean-name>
<managed-bean-class>com.ensas.jsf.exo2.HelloBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
...
Unified Expression Language
66
¨ Unified Expression Language (UEL) est un «langage» avec une syntaxe spéciale
¤ Permet d’Interagir avec les beans
¤ Syntaxe: # {expression}
¨ Nouveaux opérateurs :
¤ Arithmétiques : div et mod
¤ Logiques : and, or, not
¤ Relationels : ==, eq , !=, ne , <, lt , >, gt , <=, le , >= , ge
n Ces opérateurs peuvent comparer des primitives et des objets String
¤ empty : test si
n une valeur est null
n ou un tableau, ou une liste est vide

Accéder à
Properties #{person.name} ou bien #{person['name’]}
Arrays, Lists #{bean.tab[2]}
Maps #{bean.map['key']}
Methods #{bean.methodName}
Exo1:
67
¨ Créer une page qui permet d’entrer un nom et lui dire bonjour dans une autre page:
Exo1:
68
Exo2:
69
¨ Créer une page qui permet d’entrer un nom et lui dire bonjour dans la même page:
Exo2:
70
Exo2:
71
Exo3:
72

¨ Même exercice précédent en initialisant la propriété d’un bean par


un autre:
Exo3:
73
La navigation JSF
74

¨ Les applications web sont formées de plusieurs pages entre lesquelles on navigue.
¨ JSF dispose de plusieurs options de navigation et permet de contrôler le flux de navigation
page par page ou pour toute l’application.
¨ La navigation JSF est basée sur les règles de navigation
¤ Une règle de navigation est indexée sur le message (String) appelé résultat

¤ Un résultat nul signifie, "Rester sur la vue actuelle"


¨ Les règles de navigation peuvent être implicites ou explicites
¤ Les règles explicites sont déclarés dans faces-config.xml grâce au balisage <navigation-
rules>
¤ Les règles implicites n’ont pas besoin d’être déclarés

¨ Par exemple
¤ Lorsqu’on envoie un formulaire, la page suivante affichée est définie par une règle de
navigation.
¨ Résolution de la navigation en fonction de l'action from-action
¤ JSF fournit une option de résolution de navigation même si des méthodes différentes du bean
géré renvoient le même nom de vue.
La navigation JSF
75

¨ Navigation explicite
¤ Dans faces-config.xml
...
<navigation-rule>
<from-view-id>/startPage.xhtml </from-view-id>
<navigation-case>
<from-outcome>return_value</from-outcome>
<to-view-id>/destinationPage.xhtml </to-view-id>
</navigation-case>
</navigation-rule>
...

¤ return_value est la valeur de retour action d’un tag de navigation.


¤ Une règle de navigation peut avoir plusieurs cas de navigation…
La navigation JSF
76

¨ Navigation explicite
¤ La tag <navigation-rule> permet de préciser des règles de
navigation.
¤ La tag <from-view-id> permet de préciser la page concernée. Ce
tag n'est pas obligatoire : sans sa présence, il est possible de définir
une règle de navigation applicable à toutes les pages JSF de
l'application.
<navigation-rule>
<navigation-case>
<from-outcome> logout </from-outcome>
<to-view-id>/deconnexion.xhtml </to-view-id>
</navigation-case>
</navigation-rule>

¤ Il est aussi possible de désigner un ensemble de pages dans le tag


<from-view-id> en utilisant le caractère * dans la valeur du tag. Ce
caractère * ne peut être utilisé qu'une seule fois dans la valeur du
tag et il doit être en dernière position.
<from-view-id>/admin/* </from-view-id >
La navigation JSF
77

¨ Navigation explicite
¤ Le tag <navigation-case> permet de définir les différents cas.
¤ La valeur du tag <from-outcome> doit correspondre au nom d'une action.
¤ Le tag <to-view-id> permet de préciser la page qui sera affichée. L'URL fournie
comme valeur doit commencer par un slash et doit préciser une page possédant
une extension brute (ne surtout pas mettre une URL utilisée par la servlet faisant
office de contrôleur).
¤ Le tag <redirect/> inséré juste après le tag <to-view-id> permet au navigateur
de l'utilisateur d'effectuer la redirection vers la page indiquée.
¤ La gestion de la navigation est assurée par une instance de la classe
NavigationHandler, gérée au niveau de l'application. Ce gestionnaire utilise la
valeur d'un attribut action d'un composant pour déterminer la page suivante et
faire la redirection vers la page adéquate en fonction des informations fournies
dans le fichier de configuration.
¤ La valeur de l'attribut action peut être statique : dans ce cas la valeur est en dur
dans le code de la vue
¤ La valeur de l'attribut action peut être dynamique : dans ce cas la valeur est
déterminée par l'appel d'une méthode d'un bean
Statique : <h:commandButton action="login"/>
Dynamique: <h:commandButton action="#{login.verifierMotDePasse}"/>
La navigation JSF
78

¨ Navigation explicite (exemple)


¤ La valeur de retour est définie dans l'attribut d'action
<h:form>
<h:commandLink action="success" value="Submit" />
</h:form>

¤ L'utilisateur est redirigé vers order.xhtml


...
<navigation-rule>
<from-view-id>/index.xhtml </from-view-id>
<navigation-case>
<from-outcome> success </from-outcome>
<to-view-id>/order.xhtml </to-view-id>
</navigation-case>
</navigation-rule>
...
La navigation JSF
79

¨ Navigation implicite
¤ JSF 2 prend désormais en charge la navigation implicite
n Pas besoin de définir une règle de navigation dans le fichier de
configuration JSF!
¤ Si un income (valeur départ) n'est pas déclaré, JSF essaiera de
trouver et de rendre une vue avec la valeur du résultat comme nom.
n Exemple:
Une valeur de résultat non déclarée «listProducts» rendra (le cas échéant) la
page listProducts.xhtml (ou listProducts.jsp).
La navigation JSF
80

¨ Navigation implicite
¤ La valeur de retour est définie dans l'attribut action
¤ L’envoi du formulaire suivant:
<h:form>
<h:commandLink action="page2" value="Submit" />
</h:form>

¤ … Essayera de rendre une vue nommée page2.xhtml


¨ Type de navigation : On a deux types de navigation:
¤ Navigation statique
n Le résultat est connu quand la page JSP est interprétée
<h:commandButton action="success" />

¤ Navigation dynamique
n Le résultat est inconnu lorsque la page est interprétée grâce à EL
<h:commandButton action="#{bean.action}" />
La navigation JSF
81

¨ Forward / Redirect (Transférer / rediriger)


¤ Lors de la navigation vers une autre page
n JSF effectue un transfert (comportement par défaut) vers la nouvelle page.
¤ Problèmes de transfert de serveur : le comportement par défaut lors de la
navigation vers une autre page c’est le transfert de serveur
n Le navigateur ne sait pas qu’on affiche une page différente
n L’adresse de la page dans l’URL ne change pas!
¤ Mais JSF fournit un moyen de forcer la redirection au lieu de transférer…
n Exemple avec une règle de navigation implicite:
<h:commandButton action="success?faces-redirect=true" />
n Exemple avec une règle de navigation explicite:
...
<navigation-rule>
<from-view-id>/index.xhtml </from-view-id>
<navigation-case>
<from-outcome> success </from-outcome>
<to-view-id>/order.xhtml </to-view-id>
</navigation-case>
<redirect/>
</navigation-rule>
...
La navigation JSF (Exercice)
82

¨ Créer 3 pages (index, page1, page2) pour tester la navigation JSF.


La navigation JSF (Exercice)
83
La navigation JSF (Exercice)
84
La navigation JSF (Exercice)
85
Internationalization (I18N)
86

¨ Il permet de fournir des applications localisées


¤ Cette fonctionnalité est basée sur les fichiers de propriétés nommé sous la forme :
<file-name>_<locale>.properties , avec locale qui indique la langue: en, fr, …
n lang_en.properties
my_message=My favorite web site
n lang.properties
my_message=Mon site préféré
¤ Tous doivent contenir les mêmes clés
¨ Comment gérer ces valeurs?
¤ Depuis les pages Web, on appel la balise <f: loadBundle>.
¤ On peut également utiliser EL pour récupérer des entrées
<f:view locale="en_EN" /> <!-- pour forcer le changement de la langue -->
<f:loadBundle basename="com.example.helloJSF.resources.lang" var="msg"/>
<f:view>
<h:outputText value="#{msg.my_message}"/>
<h:outputText value="#{msg['my_message']}"/>
</f:view>
¤ Une valeur différente apparaît en fonction de la langue sélectionnée
Internationalisation (I18N)
87

¨ Comment gérer ces valeurs?


¤ Depuis également le fichier de configuration faces-config.xml:
<application>
<resource-bundle>
<base-name>com.example.helloJSF.resources.lang</base-name>
<var>msg</var>
</resource-bundle>
<locale-config>
<default-locale>fr</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>es</supported-locale>
</locale-config>
</application>
<f:view locale="en_EN" /> <!-- pour forcer le changement de la langue -->

<f:view>
<h:outputText value="#{msg.my_message}"/>
</f:view>

¤ On peut modifier les paramètres régionaux d’une application par


programmation comme ceci:
// cet exemple change le locale vers france
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale('fr');
Internationalization (Exercice)
88

¨ Créer un projet JSF contenant une page permettant l’affichage de message


en langue choisie comme suit:
Internationalization (Exercice)
89
Internationalization (Exercice)
90

¨ Comment
Internationalization (Exercice)
91

¨ Créer un projet JSF contenant une page permettant le choix de langue par
l’utilisateur comme suit:
Internationalization (Exercice)
92
Internationalization (Exercice)
93
Internationalization (Exercice)
94
Internationalization (Exercice)
95
Composants JSF
96

¨ JSF propose un ensemble de composants serveurs pour faciliter


le développement d'interfaces graphiques utilisateur.
¨ Pour les composants, JSF propose :
¤ un ensemble de classes qui gèrent le comportement et l'état d'un
composant
¤ un modèle pour assurer le rendu du composant pour un type
d'application (par exemple HTML)
¤ un modèle de gestion des événements émis par le composant
reposant sur le modèle des listeners
¤ la possibilité d'associer à un composant un moyen de conversion de
données ou de validation des données
¨ Tous ces composants héritent de la classe abstraite
UIComponentBase , qui hérite elle aussi de UIComponent .
Composants JSF
97
Composants JSF
98
¨ Un composant JSF est composé de :
¤ Une classe
public class UIComponent {
private String id;
public String getId() { ... }
public void setId(…) { ... }
...
}
¤ Un balisage
<h:baliseJSF id="identifier" />

¨ Tous les composants communs ont ces attributs


¤ id: l'identifiant du composant
¤ rendered : définit si le composant est visible ou non
¤ binding : permet de lier la valeur du composant avec la propriété d'un bean.
¨ Tous les composants de base sont divisés en deux parties:
¤ https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/toc.htm
n Composants logiques
n Exemple: convertisseurs, paramètres,…
¤ https://docs.oracle.com/javaee/7/javaserver-faces-2-2/renderkitdocs/toc.htm
n Composants de Rendu HTML
n Exemple: formulaire, champs,…
Composants JSF standard
99

Composant Description
UICommand Composant qui permet de réaliser une action émettant un événement
Composant qui regroupe d'autres composants dont l'état sera renvoyé
UIForm
au serveur
UIGraphic Composant qui représente une image
UIInput Composant qui permet de saisir des données
UIOutput Composant qui permet d'afficher des données
Composant qui regroupe les composants à afficher sous forme d'un
UIPanel
tableau
Composant UIComponent qui représente un paramètre de
UIParameter
configuration nommé en option pour un composant parent.
UISelectItem Composant qui représente un élément sélectionné dans un ensemble
UISelectItems Composant qui représente un ensemble d'éléments
UISelectBoolean Composant qui permet de sélectionner parmi deux états
Composant qui permet de sélectionner plusieurs éléments d'un
UISelectMany
Composants JSF standard
100

inputText commandButton commandLink dataTable

selectBooleanCheckbox selectOneRadio panelGrid

graphicImage inputTextarea inputSecret


Composants JSF standard
101
¨ Déclarer un formulaire :
<h:form>
<!-- Form fields - champs du formulaire -->
</h:form>

¨ Comme un formulaire HTML, mais pas d'attribut method : La méthode post est utilisée
par défaut
¨ Il possède les attributs suivants :
Attribut Rôle
binding, id, rendered, styleClass attributs communs de base
accept, acceptcharset, dir, enctype, lang, style, target, title attributs communs liés à HTML
onblur, onchange, onclick, ondblclick, onfocus, onkeydown,
attributs communs liés aux
onkeypress, onkeyup, onmousedown, onmousemove,
événements JavaScript
onmouseout, onmouseover, onreset, onsubmit
¨ Il est préférable de définir explicitement l'attribut id pour permettre son exploitation
notamment dans le code JavaScript, sinon un id est généré automatiquement.
¨ Ceci est d'autant plus important que les id des composants intégrés dans le
formulaire sont préfixés par l'id du formulaire suivi du caractère deux-points. Il faut
tenir compte de ce point lors de l'utilisation de code JavaScript faisant référence à un
composant.
Composants JSF standard
102

¨ Afficher un texte
¤ <h: outputText> et <h: outputLabel>
¤ L'attribut value définit la valeur à afficher

¤ L’attribut for permet de lier <h: outputText> et <h:


outputLabel>
<p>
<h:outputText value="My Text" />
</p>

<h:outputLabel value="First Name:" for="firstName" />

<h:inputText id="firstName" value="Your first name" />


Composants JSF standard
103

¨ Le tag <ouputText> et <outputFormat> permettent d'insérer dans la vue une


valeur sous la forme d'une chaîne de caractères.
¨ Par défaut, ils ne génèrent pas de tags HTML mais insèrent simplement la
valeur dans la vue sauf si un style CSS est précisé avec l'attribut style ou
styleClass. Dans ce cas, la valeur est contenue dans un tag HTML <span>.
¨ Les attributs de ces deux tags sont :
Attribut Rôle
booléen qui précise si certains caractères de la valeur
escape
seront encodés ou non. La valeur par défaut est false.
binding, converter, id, rendered,
attributs communs de base
styleClass, value
style, title attributs communs liés à HTML
¨ L'attribut escape est particulièrement utile pour encoder certains caractères
spéciaux avec leur code HTML correspondant.
<h:outputText escape="true" value="Nombre d’occurrences > 200"/>
Composants JSF standard
104
¨ Le tag outputText peut être utilisé pour générer du code HTML en valorisant l'attribut
escape à false.
<p><h:outputText escape="false" value="&lt;H2&gt;Saisie des données&lt;/H2&gt;"/></p>
<p><h:outputText escape="true" value="&lt;H2&gt;Saisie des données&lt;/H2&gt;"/></p>

¨ Le tag <outputFormat> permet de formater une chaîne de caractères avec des


valeurs fournies en paramètres.
<p>
<h:outputFormat value="La valeur doit être entre {0} et {1}.">
<f:param value="1"/>
<f:param value="9"/>
</h:outputFormat>
</p>

¨ Ce composant utilise la classe java.text.MessageFormat pour formater le message.


L'attribut value doit donc contenir une chaîne de caractères utilisable par cette classe.
¨ Le tag <param> permet de fournir la valeur de chacun des paramètres.
Composants JSF standard
105

¨ Champs de texte pour la saisie de données


¤ <h: inputText>, <h: inputTextarea>, <h: inputSecret> et
<h: inputHidden>
¤ La valeur d'attribut contient la valeur actuelle du composant
(peut être une expression EL)
<div>
<h:inputText value="Default value" />
</div>

<!– Le Rendu en HTML -->


<div>
<input type="text" value="Default value" />
</div>

¨ Les attributs de ces tags sont :


Attribut Rôle

cols Composants JSF standard définir le nombre de colonnes (pour le


composant inputTextarea uniquement)
permettre de demander d'ignorer les étapes
immediate
106
de validation des données
¨ Les attributs de ces tags sont les suivants :
permettre de réafficher le contenu lors du
redisplay réaffichage de la page (pour le composant
inputSecret uniquement)
required rendre obligatoire la saisie d'une valeur
définir le nombre de lignes affichées (pour le
rows
composant inputTextarea uniquement)
préciser une classe de type listener lors du
valueChangeListener
changement de la valeur
binding, converter, id, rendered, required,
attributs communs de base
styleClass, value, validator
accesskey, alt, dir, disabled,lang, maxlength,
attributs communs liés à HTML
readonly, size, style, tabindex, title
onblur, onchange, onclick, ondblclick, onfocus,
attributs communs liés aux événements
onkeydown, onkeypress, onkeyup, onmousedown,
JavaScript
onmousemove, onmouseout, onmouseover, onselect
Composants JSF standard
107

¨ Le tag <inputHidden> représente un champ caché dans


un formulaire.
¨ Les attributs sont les suivants :
Attribut Rôle
AttributRôlebinding, converter, id, immediate, required, validator, attributs communs de base
value, valueChangeListener

<h:inputHidden value="#{login.nom}" />


Composants JSF standard
108

¨ Le tag <commandButton> et <commandLink> représentent


respectivement un bouton de formulaire et un lien qui
déclenche une action. L'action demandée sera traitée par le
framework JSF.
¨ Boutons : <h: commandButton >
¤ Utilisé pour la validation du formulaire
¤ L'attribut action permet de définir des règles de navigation
<h:form>
<h:commandButton action="success" value="Send" />
</h:form>

¤ On peut aussi appeler une méthode depuis l'intérieur de l'attribut


<h:form>
<h:commandButton action="#{messageController.sendMessage}" value="Send" />
</h:form>

¨ Les attributs sont les suivants :


Attribut Rôle
peut être une chaîne de caractères ou une
action Composants JSF standard méthode qui renvoie une chaîne de caractère
qui sera traitée par le navigation handler.
109
précise une méthode possédant une signature
actionListener void nomMethode(ActionEvent) qui sera
exécutée lors d'un clic
URL tenant compte du contexte de
l'application pour l'image qui sera utilisée à
image
la place du bouton (uniquement pour le tag
commandButton)
type de bouton généré : button, submit, reset
type
(uniquement pour le tag commandButton)
value le texte affiché par le bouton ou le lien
accesskey, alt, binding, id, lang, rendered, styleClass attributs communs de base
onblur, onchange, onclick, ondblclick, onfocus, onselect
attributs communs liés aux événements
onkeydown, onkeypress, onkeyup, onmousedown,
JavaScript
onmousemove, onmouseout, onmouseover, onmouseup
coords (uniquement pour le tag commandLink), dir, disabled, hreflang (uniquement pour le tag
commandLink), lang, readonly, rel (uniquement pour le tag commandLink), rev (uniquement pour le
tag commandLink), shape (uniquement pour le tag commandLink), style, tabindex, target (uniquement
pour le tag commandLink), title (attributs communs liés à HTML)
Composants JSF standard
110

¨ Il est possible d'insérer dans le corps du tag <commandLink>


d'autres composants qui feront partie intégrante du lien comme
par exemple du texte ou une image.
<h:form>
<h:commandLink> <h:outputText value="Valider"/>. </h:commandLink>
<h:commandLink>
<h:graphicImage value="/resources/images/oeil1.png"/>
</h:commandLink>
</h:form>

¨ Il est aussi possible de fournir un ou plusieurs paramètres qui


seront envoyés dans la requête en utilisant le tag <param>
dans le corps du tag
<h:form>
<h:commandLink>
<h:outputText value="Selectionner"/>
<f:param name="id" value="1"/>
</h:commandLink>
</h:form>
Composants JSF standard
111

¨ Liens:
¤ <h: outputLink>
n L'URL est définie par l'attribut value
n Le texte est défini par le texte imbriqué dans la balise elle même
<h:outputLink value="Contacts.xhtml">
<h:outputText value="Contacts" />
</h:ouputLink>

¤ <h: commandLink>
n Doit être imbriqué dans une balise <h: form>
n L'attribut action est utilisé par la navigation.
<h:form>
<h:commandLink action="outcome" value="Mon lien" />
</h:form>
Composants JSF standard
112
¨ Le tag <outputLink> représente un lien direct vers une ressource dont la demande ne sera
pas traitée par le framework JSF. Les attributs sont les suivants :
Attribut Rôle
accesskey, binding, converter, id, lang, rendered, styleClass, value attributs communs de base
charset, coords, dir, hreflang, lang, rel, rev, shape, style, tabindex, target, title,
attributs communs liés à HTML
type
onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, attributs communs liés aux
onmousedown, onmousemove, onmouseout, onmouseover, onmouseup événements JavaScript
¨ L'attribut value doit contenir l'URL qui sera utilisée dans l'attribut href du lien HTML. Si le
premier caractère est un # (dièse) alors le lien pointe vers une ancre définie dans la même
page.
¨ Il est possible d'insérer dans le corps du tag outputLink d'autres composants qui feront partie
intégrante du lien.
¨ Attention, pour mettre du texte dans le corps du tag, il est nécessaire d'utiliser un tag verbatim
ou outputText.
<h:outputLink value="http://java.sun.com">
<h:graphicImage value="/resources/images/java.png"/>
</h:outputLink> <br />
<h:outputLink value="http://java.sun.com" title="Java">
<f:verbatim> Site Java de Sun </f:verbatim>
</h:outputLink>
Composants JSF standard
113

¨ Case à cocher
¤ <h: selectBooleanCheckbox>
n Case à cocher avec un seul choix
n L’attribut value définit si le composant est coché

<h:outputLabel for="choice" value="Ma case a cocher" />


<h:selectBooleanCheckbox id="choice" value="#{bean.property}" />

¤ <h: selectManyCheckbox>
n Imprimer une liste de cases à cocher
n Déclarer des éléments: <f: selectItem> ou <f: selectItems>
n L’attribut value est une collection où les éléments sélectionnés seront
stockés
n La valeur est primitive, un nombre ou une chaîne
Composants JSF standard
114
¨ Les tags <selectBooleanCheckbox> et <selectManyCheckbox> représentent
respectivement une case à cocher et un ensemble de cases à cocher. Les attributs sont:
Attribut Rôle
classe CSS pour les éléments non sélectionnés
disabledClass
(pour le tag selectManyCheckbox uniquement)
classe CSS pour les éléments sélectionnés
enabledClass
(pour le tag selectManyCheckbox uniquement)
préciser la disposition des éléments
layout
(pour le tag selectManyCheckbox uniquement)
binding, converter, id, immediate, styleClass, value,
attributs communs de base
required, rendered, validator,valueChangeListener
accesskey, border, dir, disabled, lang, readonly, attributs communs liés à HTML (border pour le
style, tabindex, title tag selectManyCheckbox uniquement)
onblur, onchange, onclick, ondblclick, onfocus,
onkeydown, onkeypress, onkeyup, onmousedown, attributs communs liés aux événements
onmousemove, onmouseout, onmouseover, JavaScript
onmouseup, onselect
Composants JSF standard
115
¨ L'attribut layout permet de préciser la disposition des cases à cocher : lineDirection
pour une disposition horizontale (c'est la valeur par défaut) et pageDirection pour
une disposition verticale.
¨ Le tag <selectBooleanCheckbox> dont la valeur peut être associée à une propriété
booléenne d'un bean représente une case à cocher simple.
¨ Pour gérer l'état du composant, il faut utiliser l'attribut value en lui fournissant la
valeur d'une propriété booléen d'un backing bean.
¨ Le tag <selectManyCheckbox> représente un ensemble de cases à cocher. Dans cet
ensemble, il est possible d'en sélectionner une ou plusieurs.
¨ Chaque case à cocher est définie par un tag selectItem dans le corps du tag
selectManyCheckbox.
¨ Le rendu du composant est un tableau HTML dont chaque cellule contient une case à
cocher encapsulée dans un tag HTML <label>
<h:selectManyCheckbox value="#{bean.taille}" layout="pageDirection">
<f:selectItem itemValue="petit" itemLabel="Petit" />
<f:selectItem itemValue="moyen" itemLabel="Moyen" />
<f:selectItem itemValue="grand" itemLabel="Grand" />
</h:selectManyCheckbox>
Composants JSF standard
116
¨ Bouton radio
¤ <h: selectOneRadio>
¤ La déclaration est similaire à <h: selectManyCheckbox>
¤ L’attribut value stocke le choix de l’utilisateur
<h:selectOneRadio value="#{bean.color}" layout="lineDirection">
<f:selectItem itemValue="red" itemLabel="red" />
<f:selectItem itemValue="white" itemLabel="white" />
<f:selectItem itemValue="yellow" itemLabel="yellow" />
</h:selectOneRadio>

¤ Les éléments peuvent être précisés sous la forme d'un tableau de type SelecItem avec le
tag <selectItems>.
<h:selectOneRadio value="#{saisieOptions.taille}" layout="pageDirection" id="taille">
<f:selectItems value="#{saisieOptions.tailleItems}"/>
</h:selectOneRadio>
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
@ManagedBean
public class SaisieOptions {
private Integer taille = new Integer(3); //choix par défaut
private SelectItem[] tailleItems = {new SelectItem(new Integer(1), "Petit"),
new SelectItem(new Integer(2), "Moyen"), new SelectItem(new Integer(3), "Grand")};
public Integer getTaille() { return taille; }
public void setTaille(Integer newValue) { taille = newValue; }
public SelectItem[] getTailleItems() { return tailleItems; }
}
Composants JSF standard
117
¨ Le tag <selectOneRadio> représente un ensemble de boutons radio dont un seul
peut être sélectionné. Les attributs sont :
Attribut Rôle
classe CSS pour les éléments non
disabledClass
sélectionnés
classe CSS pour les éléments
enabledClass
sélectionnés
layout préciser la disposition des éléments
binding, converter, id, immediate, styleClass, value,
Attributs communs de base
required, rendered, validator, valueChangeListener
accesskey, border, dir, disabled, lang, readonly, style,
Attributs communs liés à HTML
tabindex, title
onblur, onchange, onclick, ondblclick, onfocus, onselect,
Attributs communs liés aux événements
onkeydown, onkeypress, onkeyup, onmousedown,
JavaScript
onmousemove, onmouseout, onmouseover, onmouseup
¨ Les éléments peuvent être précisés sous la forme d'un tableau de type SelecItem avec
le tag <selectItems>.
Composants JSF standard
118
¨ Le tag <selectOneListbox> représente une liste d'éléments dont un seul peut être sélectionné.
Les attributs sont :
Attribut Rôle
binding, converter, id, immediate, styleClass, required, rendered, validator,
attributs communs de base
value, valueChangeListener
accesskey, dir, disabled, lang, readonly, style, size, tabindex, title attributs communs liés à HTML
onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onselect, attributs communs liés aux
onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, événements JavaScript
¨ Les éléments peuvent être précisés sous la forme d'un tableau de type SelecItem avec le tag
<selectItems>.
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
@ManagedBean
public class SaisieOptions {
private Integer taille = new Integer(3); //choix par défaut
private SelectItem[] tailleItems = {new SelectItem(new Integer(1), "Petit"),
new SelectItem(new Integer(2), "Moyen"), new SelectItem(new Integer(3), "Grand")};
public Integer getTaille() { return taille; }
public void setTaille(Integer newValue) { taille = newValue; }
public SelectItem[] getTailleItems() { return tailleItems; }
}
<h:selectOneListbox value="#{saisieOptions.taille}">
<f:selectItems value="#{saisieOptions.tailleItems}"/>
</h:selectOneListbox>
Composants JSF standard
119

¨ Le tag <selectManyListbox> représente une liste d'éléments dont plusieurs


peuvent être sélectionnés. Les attributs sont :
Attribut Rôle
binding, converter, id, immediate, styleClass, required, rendered,
attributs communs de base
validator, value, valueChangeListener
attributs communs liés à
accesskey, dir, disabled, lang, readonly, style, size, tabindex, title
HTML
onblur, onchange, onclick, ondblclick, onfocus, onkeydown,
attributs communs liés aux
onkeypress, onkeyup, onmousedown, onmousemove, onmouseout,
événements JavaScript
onmouseover, onmouseup, onselect
¨ La liste des éléments sélectionnés doit pouvoir contenir zéro ou plusieurs
valeurs sous la forme d'un tableau ou d'une liste. Il est possible d'utiliser un
objet de type List à la place des tableaux.
<h:selectManyListbox value="#{saisieLegumes.legumes}">
<f:selectItems value="#{saisieLegumes.legumesItems}"/>
</h:selectManyListbox>
Composants JSF standard
120
import java.util.*;
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
@ManagedBean
public class SaisieLegumes {
private List<String> legumes = null;
private List<SelectItem> legumesItems = null;
public SaisieLegumes() {
legumes = new ArrayList<String>();
legumes.add("navets");
legumes.add("choux");
}
public List<SelectItem> getLegumesItems() {
if (legumesItems == null) {
legumesItems = new ArrayList<SelectItem>();
legumesItems.add(new SelectItem("epinards", "Epinards"));
legumesItems.add(new SelectItem("navets", "Navets"));
legumesItems.add(new SelectItem("poireaux", "Poireaux"));
legumesItems.add(new SelectItem("choux", "Choux"));}
return legumesItems;
}
public List<String> getLegumes() {
return legumes;
}
public void setLegumes(List<String> newValue) {
legumes = newValue;
}
}
<h:selectManyListbox value="#{saisieLegumes.legumes}">
<f:selectItems value="#{saisieLegumes.legumesItems}"/>
</h:selectManyListbox>
Composants JSF standard
121

¨ Le tag <selectOneMenu> représente une liste déroulante dont


un seul élément peut être sélectionné. Les attributs sont :
Attribut Rôle
binding, converter, id, immediate, styleClass, required,
attributs communs de base
rendered, validator, value, valueChangeListener
attributs communs liés à
accesskey, dir, disabled, lang, readonly, style, tabindex, title
HTML
onblur, onchange, onclick, ondblclick, onfocus, onkeydown,
attributs communs liés aux
onkeypress, onkeyup, onmousedown, onmousemove,
événements JavaScript
onmouseout, onmouseover, onmouseup, onselect

<h:selectOneMenu value="#{saisieOptions.taille}">
<f:selectItems value="#{saisieOptions.tailleItems}"/>
</h:selectOneMenu>
Composants JSF standard
122

¨ Le tag <selectManyMenu> représente une liste d'éléments dont le


rendu HTML est un tag select avec une seule option visible. Les
attributs sont :
Attribut Rôle
binding, converter, id, immediate, styleClass, required, rendered,
Attributs communs de base
validator, value, valueChangeListener
Attributs communs liés à
accesskey, dir, disabled, lang, readonly, style, tabindex, title
HTML
onblur, onchange, onclick, ondblclick, onfocus, onkeydown,
Attributs communs liés aux
onkeypress, onkeyup, onmousedown, onmousemove, onmouseout,
événements JavaScript
onmouseover, onmouseup, onselect

<h:selectManyMenu value="#{saisieLegumes.legumes}">
<f:selectItems value="#{saisieLegumes.legumesItems}"/>
</h:selectManyMenu>
Composants JSF standard
123

¨ Le tag <panelGroup> permet de regrouper plusieurs


composants. Les attributs sont :
Attribut Rôle
binding, id, rendered, styleClass attributs communs de base
style style CSS

<td bgcolor='#DDDDDD'>
<h:panelGroup>
<h:inputText value="#{myBean.message}" id="nom" required="true"/>
<h:message for="nom"/>
</h:panelGroup>
</td>
Composants JSF standard
124

¨ Table

¤ Grille statique: <h: panelGrid> (on doit connaître sa taille)


¤ Très utile parfois pour la disposition des composant

<h:panelGrid border="1" columns="2">


<f:facet name="header">
<h:outputText value="Header Text" />
</f:facet>
<f:facet name="footer">
<h:panelGroup>
<h:outputText value="Footer text" />
</h:panelGroup>
</f:facet>
<h:outputText value="A" />
<h:outputText value="B" />
<h:outputText value="C" />
<h:outputText value="D" />
</h:panelGrid>
Composants JSF standard
125

¨ Le tag <panelGrid> représente un tableau HTML. Les attributs sont :


Attribut Rôle
bgcolor couleur de fond du tableau
border taille de la bordure du tableau
cellpadding espacement intérieur de chaque cellule
cellspacing espacement extérieur de chaque cellule
nom de classes CSS pour les colonnes. Il est possible de préciser plusieurs noms de
columnClasses
classes qui seront utilisées sur chaque colonne
columns nombre de colonnes du tableau
footerClass nom de la classe CSS pour le pied du tableau
précise les règles pour le contour du tableau. Les valeurs possibles sont : none,
frame
above, below, hsides, vsides, lhs, rhs, box, border
headerClass nom de la classe CSS pour l'en-tête du tableau
nom de classes CSS pour les lignes. Il est possible de préciser deux noms de
rowClasses
classes séparés par une virgule qui seront utilisés alternativement sur chaque ligne
Composants JSF standard
126

Attribut Rôle
précise les règles de dessin des lignes entre les cellules.
rules
Les valeurs possibles sont : groups, rows, columns, all
summary résumé du tableau
binding, id, rendered, styleClass, value attributs communs de base
dir, lang, style, title, width attributs communs liés à HTML

onclick, ondblclick, onkeydown,


onkeypress, onkeyup, onkeyup,
attributs communs liées aux événements JavaScript
onmousedown, onmousemove,
onmouseout, onmouseover, onmouseup

¨ Par défaut les composants sont insérés les uns à la suite des autres dans les cellules en
partant de la gauche vers la droite et en passant à la ligne suivante si nécessaire.
¨ Il est possible de ne mettre qu'un seul composant par cellule. Ainsi pour placer
plusieurs composants dans une cellule, il faut les regrouper dans un tag panelGroup.
Composants JSF standard
127
<h:panelGrid columns="2">
<h:outputText value="Nom : " />
<h:panelGroup>
<h:inputText value="#{login.nom}" id="nom" required="true"/>
<h:message for="nom"/>
</h:panelGroup>
<h:outputText value="Mot de passe :" />
<h:inputSecret value="#{login.mdp}"/>
<h:commandButton value="Login" action="login"/>
</h:panelGrid>
import javax.faces.bean.ManagedBean;
@ManagedBean
public class Login {
private String nom;
private String mdp;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getMdp() {
return mdp;
}
public void setMdp(String mdp) {
this.mdp = mdp;
}
}
Composants JSF standard
128

¨ Table dynamique
¤ Table dynamique: <h: dataTable>
¤ Utile pour les tableaux, les listes et les ensembles de résultats
Java (utilisés avec JDBC)

<h:dataTable border=6 value="#{bean.dataModel}" var="line">


<h:column>
<f:facet name="header">
<h:outputText value="Header text" />
</f:facet>
<h:outputText value="#{line.property}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Header text 2" />
</f:facet>
<h:outputText value="#{line.property2}" />
</h:column>
</h:dataTable>
Composants JSF standard
129

¨ Le tag <dataTable> représente un tableau HTML dans lequel des données


vont pouvoir être automatiquement présentées. Ce composant est sûrement le
plus riche en fonctionnalité et donc le plus complexe des composants fournis
en standard. Les attributs sont :
Attribut Rôle
bgcolor couleur de fond du tableau
border taille de la bordure du tableau
cellpadding espacement intérieur de chaque cellule
cellspacing espacement extérieur de chaque cellule
nom de classes CSS pour les colonnes. Il est possible de préciser plusieurs noms
columnClasses
de classes qui seront utilisées sur chaque colonne
first index de la première occurrence des données qui sera affichée dans le tableau
footerClass nom de la classe CSS pour le pied du tableau
précise les règles pour le contour du tableau. Les valeurs possibles sont : none,
frame
above, below, hsides, vsides, lhs, rhs, box, border
headerClass nom de la classe CSS pour l'en-tête du tableau
Composants JSF standard
130

Attribut Rôle
nom de classes CSS pour les lignes. Il est possible de préciser deux
rowClasses
noms de classes qui seront utilisées alternativement sur chaque ligne
précise les règles de dessin des lignes entre les cellules. Les valeurs
rules
possibles sont : groups, rows, columns, all
summary résumé du tableau
nom de la variable qui va contenir l'occurrence en cours de
var
traitement lors du parcours des données
binding, id, rendered,
attributs communs de base
styleClass, value
dir, lang, style, title, width attributs communs liés à HTML
onclick, ondblclick,
onkeydown, onkeypress,
onkeyup, onmousedown, attributs communs liés aux événements JavaScript
onmousemove, onmouseout,
onmouseover, onmouseup
Composants JSF standard
131
¨ Le tag <dataTable> parcourt les données et pour chaque occurrence, il crée une ligne dans le
tableau.
¨ L'attribut value représente une expression qui précise les données à utiliser. Ces données peuvent
être sous la forme :
¤ d'un tableau
¤ d'un objet de type java.util.List
¤ d'un objet de type java.sql.ResultSet
¤ d'un objet de type javax.servlet.jsp.jstl.sql.Result
¤ d'un objet de type javax.faces.model.DataModel
¨ Pour chaque élément encapsulé dans les données, le tag dataTable crée une nouvelle ligne.
¨ Quelque soit le type qui encapsule les données, le composant dataTable va les mapper dans un
objet de type DataModel. C'est cet objet que le composant va utiliser comme source de données.
JSF définit 5 classes qui héritent de la classe DataModel : ArrayDataModel, ListDataModel,
ResultDataModel, ResultSetDataModel et ScalarDataModel.
¨ La méthode getWrappedObject() permet d'obtenir la source de données fournie en paramètre de
l'attribut value.
¨ L'attribut item permet de préciser le nom d'une variable qui va contenir les données d'une
occurrence.
¨ Chaque colonne est définie grâce à un tag <column>.
¨ L'en-tête et le pied du tableau sont précisés avec un tag <facet> pour chacun dans chaque tag
<column>.
DataModel
132

¨ DataModel est une abstraction autour de technologies de


liaison de données arbitraires
¤ Peut être utilisé pour adapter diverses sources de données à
certains composants JavaServer Faces
n Un DataTable par exemple
DataSource

Get Selected
Object
DataModel

Values SelectedRow (id row)


A B
C D Web page
DataModel
133

¨ Class & implementations


¤ Classe abstraite
n DataModel
¤ Implémentations
n ArrayDataModel: pour envelopper un tableau array
n ListDataModel: pour envelopper une liste List
n ResultDataModel: pour encapsuler le résultat JSTL
n ResultSetDataModel: pour encapsuler ResultSet
n ScalarDataModel: pour envelopper un objet Java individual
¨ Création
¤ Déclarer un modèle de données et l'instancier avec une
implémentation
DataModel model = new ListDataModel();
DataModel model2 = new ListDataModel(myList);
¤ On peut modifier (ou initialiser) les données encapsulées grâce à:
model.setWrappedData(myList);
DataModel
134

¨ Usage
¤ Utiliser le modèle de données dans un <h: dataTable>
n Cela fonctionne comme une boucle foreach
<h:dataTable value="#{bean.model}" var="p">
...
</h:dataTable>

¤ Pour obtenir l'objet sélectionné dans le dataTable


MyObject o = (MyObject) model.getRowData();
Composants JSF standard
135

¨ Exemple d’usage du tag <dataTable> :


<link href="resources/css/style.css" rel="stylesheet" type="text/css"/>
……..
<h:dataTable value="#{listePersonnes.personneItems}" var="personne" cellspacing="4" width="80%"
rowClasses="paire,impaire" headerClass="titre">
<h:column>
<f:facet name="header"> <h:outputText value="Nom" /> </f:facet>
<h:outputText value="#{personne.nom}"/>
</h:column>
<h:column>
<f:facet name="header"> <h:outputText value="Prenom" /> </f:facet>
<h:outputText value="#{personne.prenom}" />
</h:column>
<h:column>
<f:facet name="header"> <h:outputText value="Date de naissance" /> </f:facet>
<h:outputText value="#{personne.datenaiss}" />
</h:column>
<h:column>
<f:facet name="header"> <h:outputText value="Poids" /> </f:facet>
<h:outputText value="#{personne.poids}"/>
</h:column>
<h:column>
<f:facet name="header"> <h:outputText value="Taille" /> </f:facet>
<h:outputText value="#{personne.taille}"/>
</h:column>
</h:dataTable>
Composants JSF standard
136

¨ Dans l'exemple précédent le managed bean listePersonnes est une classe


dont le code est le suivant :
import java.util.*;
import javax.faces.bean.ManagedBean;
@ManagedBean
public class ListePersonnes {
private List<Personne> PersonneItems = null;
public List<Personne> getPersonneItems() {
if (PersonneItems == null) {
PersonneItems = new ArrayList<Personne>();
PersonneItems.add(new Personne("Nom1", "Prenom1",
new GregorianCalendar(1967, Calendar.OCTOBER, 22).getTime(), 10, 1.10f));
PersonneItems.add(new Personne("Nom2", "Prenom2",
new GregorianCalendar(1972, Calendar.MARCH, 10).getTime(), 20, 1.20f));
PersonneItems.add(new Personne("Nom3", "Prenom3",
new GregorianCalendar(1944, Calendar.NOVEMBER, 4).getTime(), 30, 1.30f));
}
return PersonneItems;
}
}
¨ La méthode getPersonneItems() renvoie une collection d'objets de type Personne.
¨ La classe Personne encapsule simplement les données d'une personne :
Composants JSF standard
137
import java.util.Date;
public class Personne {
private String nom;
private String prenom;
private Date datenaiss;
private int poids;
private float taille;
public Personne(String nom, String prenom, Date datenaiss, int poids, float taille) {
this.nom = nom;
this.prenom = prenom;
this.datenaiss = datenaiss;
this.poids = poids;
this.taille = taille;
}
//Getters & Setters ….
}
¨ Il est très facile de préciser un style particulier pour des lignes paires et impaires.
¨ Il suffit d'utiliser les attributs headerClass, footerClass, rowClasses ou columnClasses.
Avec ces deux derniers attributs, il est possible de préciser plusieurs styles séparés
par une virgule pour définir l'apparence de chacune des lignes de façon répétitive.
<link href="resources/css/style.css" rel="stylesheet" type="text/css"/>
……..
<h:dataTable value="#{listePersonnes.personneItems}" var="personne" cellspacing="4" width="80%"
rowClasses="paire, impaire" headerClass="titre">
Composants JSF standard
138

¨ Le fichier style.css :
.titre {
background-color:#000000;
color:#FFFFFF;
}
.paire {
background-color:#EFEFEF;
}
.impaire {
background-color:#CECECE;
}
Composants JSF standard
139

¨ Personnaliser le rendu HTML


¤ Attribut style: style CSS
<h:outputText style="font-size: 150% ; color: green" value="Hello" /> JSF

<span style="font-size: 150%; color: green">Hello</span> HTML

¤ attibrut styleClass : classe CSS


¤ attribut escape : si c’est true, alors '<', '>' et '&' sont convertis
en HTML
¤ Attributs JavaScript:
n onclick, ondblclick, onblur, onchange, onfocus,…
Composants JSF standard
140

¨ Le passage de paramètres :
¤ Passer un paramètre: <f: param>
<h:outputLink value="index.jsp">
<h:outputText value="Index"/>

<f:param name="id" value="2"/>


<f:param name="sortBy" value="price"/>

</h:outputLink>

¤ Récupérer les paramètres


<h:outputText value="id=#{param.id}, sortBy=#{param.sortBy}"/>

¤ Tester si un paramètre existe:


#{!empty param.paramName}
Conversion
141
¨ Problème: Comment afficher des objets Java dans un champ de texte?
¨ Solution : Utiliser un convertisseur
n Existant (standard)
n Crée (personnalisé)
¨ JSF propose en standard un mécanisme de conversion des données. Celui-ci repose sur un
ensemble de classes dont certaines sont fournies en standard pour des conversions de base. Il
est possible de définir ses propres classes de conversion pour répondre à des besoins
spécifiques.
¨ Ces conversions sont nécessaires car toutes les données transmises et affichées sont sous la
forme de chaînes de caractères. Cependant, leur exploitation dans les traitements nécessite
souvent qu'elles soient stockées dans un autre format pour être exploitées : exemple donnée
de type date.
¨ Toutes les données saisies par l'utilisateur sont envoyées dans la requête http sous la forme de
chaînes de caractères. Chacune de ces valeurs est désignée par « request value » dans les
spécifications de JSF.
¨ Ces valeurs sont stockées dans leurs composants respectifs dans des champs désignés par
« submitted value » dans les spécifications de JSF.
¨ Ces valeurs sont éventuellement converties implicitement ou explicitement et sont stockées dans
leurs composants respectifs dans des champs désignés par « local value ». Ensuite, ces données
sont éventuellement validées.
Conversion
142

¨ L'intérêt d'un tel procédé est de s'assurer que les données seront valides
avant de pouvoir les utiliser dans les traitements. Si la conversion ou la
validation échoue, les traitements du cyle de vie de la page sont arrêtés et
la page est réaffichée en montrant les messages d'erreurs. Sinon la phase de
mise à jour des données ( « Update model values » ) du modèle est exécutée.
¨ Les spécifications JSF imposent l'implémentation des convertisseurs suivants :
javax.faces.DateTime, javax.faces.Number, javax.faces.Boolean,
javax.faces.Byte, javax.faces.Character, javax.faces.Double,
javax.faces.Float, javax.faces.Integer, javax.faces.Long, javax.faces.Short,
javax.faces.BigDecimal et javax.faces.BigInteger.
¨ JSF effectue une conversion implicite des données lorsque celles-ci
correspondent à un type primitif, à BigDecimal ou BigInteger en utilisant les
convertisseurs appropriés.
¨ Deux convertisseurs sont proposés en standard pour mettre en oeuvre des
conversions qui ne correspondent pas à des types primitifs :
¤ le tag convertNumber : utilise le convertisseur javax.faces.Number
¤ le tag convertDateTime : utilise le convertisseur javax.faces.DateTime
Conversion
143

¨ Avant de mettre à jour le modèle du Bean géré, ces données


textuelles doivent être converties dans les objets cibles.
¨ L’opération inverse : les données seront renvoyées au client dans la
réponse pour être affichées par le navigateur.
¨ JSF convertira automatiquement la valeur du composant d’interface
dans le type standard (Integer, Date …) adéquat et inversement.
¨ Les autre Types nécessitent la création d’un convertisseur
personnalisé.
Convertisseur Description
TYPEConverter (en général ) String ßàTYPE
BigDecimalConverter String ßà java.math.BigDecimal
BigIntegerConverter String ßàjava.math.BigInteger
DateTimeConverter String ßàjava.util.Date
EnumConverter String ßàEnum
Conversion
144

¨ Convertisseurs fournis par JSF


¤ <f: converterDateTime>
n attribut dateStyle: default, short, medium, long et full
<h:inputText value="#{bean.date}">
<f:convertDateTime dateStyle="full" />
</h:inputText >
¤ <f: converterNumber>
n Attributs disponibles: maxFractionDigits, integerOnly, currencySymbol,…
<h:outputText value="#{conv.number}">
<f:convertNumber type="currency" />
</h:outputText>

¨ Usage
¤ Première solution:
<h:outputText value="#{bean.person}" converter="myConv" />

¤ Deuxième solution:
<h:outputText value="#{bean.person}">
<f:converter converterId="myConv" />
</h:outputText>
f:convertNumber
145

¨ f:convertNumber est une balise qui est utilisée pour convertir une valeur de
chaîne de caractères en un certain nombre de formats requis :
Attributs type Valeur
Type String number (par défaut) pour des réels, currency pour les monétaires et percent
pour les pourcentages
pattern String java.text.DecimalFormat ( un motif présentation). "#,##0.00 F".
maxFractionDigits int Impose une valeur limite sur le nombre de chiffres décimaux à représenter.
minFractionDigits int Si le nombre ne possède pas de valeurs décimales, les 0 sont proposés.
maxIntegerDigits int Impose une valeur limite sur le nombre de chiffres sur la partie entière de la
valeur réelle à représenter.
minIntegerDigits int Impose un nombre de chiffres sur la partie entière à représenter.
IntegerOnly Boolean Impose un nombre entier seulement
groupingUsed Boolean Prendre en compte ou pas la séparation des milliers
locale util.Locale Choix du paramètre régional à utiliser.
currencyCode String La monnaie à prendre en compte comme "EUR"
currencySymbol String Une autre monnaie non prévue par le standard
f:convertNumber (exemple)
146
import javax.faces.bean.ManagedBean;
@ManagedBean
public class ConvertNumberExemple {
private int poids;
private float prix;
private float ratio;
public ConvertNumberExemple() {
this.poids = 12345;
this.prix = 1234.5687f;
this.ratio = 0.12f;
}
// Getters & Setters
}

prix = 1234.5687f --> valeur1 (type="currency") = <h:outputText value="#{convertNumberExemple.prix}">


<f:convertNumber type="currency"/>
</h:outputText>
<br/>
poids = 12345 --> valeur2 (type="number") = <h:outputText value="#{convertNumberExemple.poids}">
<f:convertNumber type="number"/>
</h:outputText>
<br/>
ratio = 0.12f --> valeur3 (type="percent") = <h:outputText value="#{convertNumberExemple.ratio}">
<f:convertNumber type="percent"/>
</h:outputText>
<br/>
prix = 1234.5687f --> valeur4 (integerOnly="true" maxIntegerDigits="2") = <h:outputText value="#{convertNumberExemple.prix}">
<f:convertNumber integerOnly="true" maxIntegerDigits="2"/>
</h:outputText>
<br/>
prix = 1234.5687f --> valeur5 (pattern="#.##") = <h:outputText value="#{convertNumberExemple.prix}">
<f:convertNumber pattern="#.##"/>
</h:outputText>
f:convertDateTime
147
¨ f:convertDateTime est une balise qui est utilisé pour convertir une valeur de chaîne
en une date du format requis. Il sert également à valider un format de date requis :

Attributs type Valeur


Type String date (par défaut) pour prendre en compte la date uniquement,
time pour prendre en compte l'heure uniquement, ou both pour
prendre en compte à la fois la date et l'heure.
pattern String java.text.SimpleDateFormat ( un motif présentation).
dataStyle String default, short, medium, long ou full. Affiche la date avec plus ou
moins de renseignements.
timeStyle String default, short, medium, long ou full. Affiche l’heure avec plus ou
moins de renseignements.
locale Util.Locale Choix du paramètre régional à utiliser.
timeZone String Tient compte du fuseau horaire.
f:convertDateTime (exemple)
148
import java.util.Date;
import javax.faces.bean.ManagedBean;
@ManagedBean
public class ConvertDateExemple {
private Date dateNaiss;
public ConvertDateExemple() {
this.dateNaiss = new Date();
}
// Getters & Setters
}

dateNaiss=<h:outputText value="#{convertDateExemple.dateNaiss}"/> --> Date1 = <h:outputText value="#{convertDateExemple.dateNaiss}">


<f:convertDateTime pattern="MM/yyyy"/>
</h:outputText>
<br/>
dateNaiss=<h:outputText value="#{convertDateExemple.dateNaiss}"/> --> Date2 = <h:outputText value="#{convertDateExemple.dateNaiss}">
<f:convertDateTime pattern="EEE, dd MMM yyyy"/>
</h:outputText>
<br/>
dateNaiss=<h:outputText value="#{convertDateExemple.dateNaiss}"/> --> Date3 = <h:outputText value="#{convertDateExemple.dateNaiss}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
<br/>
dateNaiss=<h:outputText value="#{convertDateExemple.dateNaiss}"/> --> Date4 = <h:outputText value="#{convertDateExemple.dateNaiss}">
<f:convertDateTime dateStyle="full"/>
</h:outputText>
Conversion personnalisée
149

¨ Parfois, on a besoin d’une conversion adaptée à la situation au delà de number et date.


¨ pour cela, on peut écrire une classe qui :
¤ implémente l’interface javax.faces.convert.Converter ,
¤ étend un convertisseur existant (ex : DateTimeConverter).
¨ Cette interface possède deux méthodes :
¤ Object getAsObject(FacesContext ctx, UIComponent component, String value) : appelé lors de la
phase 2 ‘Apply Request values’
¤ String getAsString(FacesContext ctx, UIComponent component, Object value) : appelé lors de la
phase 6 ‘Render Response’ de rendu
¨ Pour définir un convertisseur personnalisé dans JSF :
¤ Créer une classe pour le convertisseur en implémentant l'interface javax.faces.convert.Converter.
¤ Remplacer et redéfinir les méthodes getAsObject () et getAsString () de l’interface Converter.
¤ Attribuer un ID unique pour le convertisseur soit en ajoutant l'annotation @FacesConverter(ID) à la
classe du convertisseur ou bien en le déclarant dans la balise converter du fichier faces-config.xml
¤ Lier la classe de convertisseur personnalisée au composant JSF via sont attribut converter ou bien via
la balise <f:converter converterId="ID" />
Conversion
150

¨ Créer des convertisseurs personnalisés


¤ En implémentant l'interface javax.faces.convert.Converter
public Object getAsObject(FacesContext context, UIComponent component, String value) {
...
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
...
}

n Tout en les déclarant dans le fichier faces-config.xml


<converter>
<description>MyConverter</description>
<converter-id>myConv</converter-id>
<converter-class>
com.example.converters.MyConverter
</converter-class>
</converter>

n Ou en utilisant l'annotation @FacesConverter


@FacesConverter
public class MyConverter implements Converter {
...
}
Conversion personnalisée
151
¨ Déclaration & Identification du convertisseur dans la classe avec l'annotation @FacesConverter:
@FacesConverter(value = "euroConverter")
public class EuroConverter implements Converter {
@Override
public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
return value;
}
@Override
public String getAsString(FacesContext ctx, UIComponent component, Object value) {
float amountInDollars = Float.parseFloat(value.toString());
double ammountInEuros = amountInDollars * 0.8;
DecimalFormat df = new DecimalFormat("###,##0.##");
return df.format(ammountInEuros);
}
}
¨ Déclaration & Identification du convertisseur dans le fichier faces-config.xml :
<converter>
<description>Convertisseur Dollar Euro</description>
<converter-id> euroConverter </converter-id>
<converter-class>
com.example.converters.EuroConverter
</converter-class>
</converter>
Usage Soit avec: < h:inputText value="#{bean.price}">
<f:converter converterId="euroConverter" />
</h:inputText>
Ou bien avec: <h:inputText value="#{bean.price}" converter="euroConverter" />
Conversion : Exo
152

¨ Ex
Validation
153
¨ Toutes les classes de validation standard implémentent l'interface
javax.faces.validator.Validator. JSF propose en standard plusieurs classes pour la validation :
¤ deux classes de validation sur une plage de données : LongRangeValidator et
DoubleRangeValidator
¤ une classe de validation de la taille d'une chaîne de caractères : LengthValidator
¨ Pour faciliter l'utilisation de ces classes, la bibliothèque de tags personnalisés Core propose
des tags dédiés à la mise en oeuvre de ces classes :
¤ validateDoubleRange : utilise la classe DoubleRangeValidator
¤ validateLongRange : utilise la classe LongRangeValidator
¤ validateLength : utilise la classe LengthValidator
¨ Ces trois tags possèdent deux attributs nommés minimum et maximum qui permettent de
préciser respectivement la valeur de début et de fin selon le Validator utilisé. L'un, l'autre ou
les deux attributs peuvent être utilisés.
¨ L'ajout d'une validation sur un composant peut se faire de plusieurs manières :
¤ ajout d'une ou plusieurs validations directement dans la page
¤ ajout par programmation d'une validation en utilisant la méthode addValidator().
¤ certaines implémentations de composants peuvent contenir des validations implicites.
¨ Pour ajouter une validation à un composant dans une page, il suffit d'insérer le tag de
validation dans le corps du tag du composant.
¨ Toutes les validations sont faites côté serveur.
Validation
154
¨ Certaines implémentations de composants peuvent contenir des validations implicites en fonction du
contexte. C'est par exemple le cas du composant <inputText> qui, lorsque son attribut required est à true,
effectue un contrôle de présence de données saisies.
¨ Les messages d'erreurs issus de ces conversions peuvent être affichés en utilisant les tags <message> ou
<messages>.
¨ Ils contiennent une description par défaut selon le validator utilisé.
¨ Pour modifier ce message par défaut ou l'internationaliser, il faut définir une clé dédiée dans le fichier
properties de définition des chaînes de caractères. Les clés définies sont :
¤ javax.faces.component.UIInput.REQUIRED
¤ javax.faces.validator.NOT_IN_RANGE
¤ javax.faces.validator.DoubleRangeValidator.MAXIMUM
¤ javax.faces.validator.DoubleRangeValidator.TYPE
¤ javax.faces.validator.DoubleRangeValidator.MINIMUM
¤ javax.faces.validator.LongRangeValidator.MAXIMUM
¤ javax.faces.validator.LongRangeValidator.MINIMUM
¤ javax.faces.validator.LongRangeValidator.TYPE
¤ javax.faces.validator.LengthValidator.MAXIMUM
¤ javax.faces.validator.LengthValidator.MINIMUM
¨ Voir :
http://svn.apache.org/repos/asf/myfaces/core/branches/2.0.x/api/src/main/resources/javax/faces/M
essages.properties
Validation
155

¨ Dans un formulaire
¤ On peut définir des contraintes pour les champs
¤ Les composants concernés qui implémentent EditableValueHolder
comme :
n h: inputText, h: inputTextarea, h: selectManyMenu,…
¨ On peut appliquer des contraintes
¤ En utilisant l'attribut required (validation implicite )
<h:inputText required="true" />

¤ En utilisant des validateurs communs: <f:validateLongRange>,


<f:validateDoubleRange>, <f:validateLength> :
<h:outputLabel for="name" value="Name:"/>
<h:inputText id="name">
<f:validateLength minimum="3" maximum="10"/>
</h:inputText>
<!--display a validation message -->
<h:message for="name" />
Validation
156

¨ Créer des validateurs personnalisés


¤ 1. En créant une méthode dans un ManagedBean. Cette méthode doit avoir une
signature similaire à celle de la méthode validate() de l'interface Validator.
public void validate(FacesContext context, UIComponent component, Object value ){
//validation process
}
n … Et appeler la méthode du validateur dans la page web :
<h:inputText validator="#{bean.validate}" />

¤ 2. En créant une classe qui implémente l'interface javax.faces.validator.Validator


public class MyValidator implements Validator {
public void validate(FacesContext tcontext, UIComponent component, Object value) throws
ValidatorException { //throw ValidatorException containing FacesMessages if error
}
}
n Déclarer le validateur par annotation (@FacesValidator) ou par XML:
<validator>
<validator-id>emailValidator</validator-id>
<validator-class>MyValidator</validator-class>
</validator>
<h:inputText>
n Utiliser le validateur comme suit :
<f:validator validatorId="emailValidator" />
</h:inputText>
Validation
157

¨ Contourner la validation
¤ Dans certains cas, il est nécessaire d'empêcher la validation. Par
exemple, dans une page de saisie d'informations disposant d'un
bouton « Valider » et « Annuler ». La validation doit être opérée
lors d'un clic sur le bouton « Valider » mais ne doit pas l'être lors
d'un clic sur le bouton « Annuler ».
¤ Pour chaque composant dont l'action doit être exécutée sans
validation, il faut mettre l'attribut immediate du composant à true.
<h:commandButton value="Annuler" action="annuler" immediate="true"/>
Validation
158
¨ Traitement des messages
¤ Les messages sont utiles pour afficher les informations de validation
¤ Utiliser l’attribut converterMessage (validatorMessage)du composant
<h:inputText id="name" converterMessage= "length must be a number greater than zero"/>

¤ Insérer des messages FacesMessages dans FacesContext


public void check(ActionEvent ae) {
//Retrieve FacesContext
FacesContext context = FacesContext.getCurrentInstance();
//Create FacesMessage
FacesMessage message = new FacesMessage( FacesMessage.SEVERITY_WARN,
"Summary", "Detail of the message" );
//Add message to the context. null is replaced by a components id (String)
context.addMessage(null, message);
}
¤ Pour afficher le message, on a deux annotations :
n <h: messages>: affiche tout les messages
n <h: message>: affiche un message associé à un identifiant
¤ On a des attributs sur ce balisage
n showDetail: true / false
n showSummary: true / false
n tooltip : true / false
Validation
159
¨ Pour internationaliser le traitement des messages, on peut utiliser:
¤ le bundle (fichier des messages .properties) dans lequel on place le texte à
internationaliser sous forme de "clef = valeur". On peut y mettre des messages de
validation personnalisés, mais il faudra qu’on les place manuellement dans le contexte
depuis la couche métier, par exemple dans un validator personnalisé en utilisant le tag
<application> et le tag <validator> du fichier faces-config.xml :
<application>
<resource-bundle>
<base-name>resources.messagevalidation</base-name>
<var>bundle1</var>
</resource-bundle>
<message-bundle>resources.messagevalidation</message-bundle>
</application>
……………………
<validator>
<validator-id>numeroDeSerie</validator-id>
<validator-class>model.NumeroDeSerieValidator</validator-class>
</validator>
<f:view locale="en_EN" /> <!--pour forcer le changement de la langue -->
<h:panelGrid columns="2">
<h:outputText value="Numéro de série : " />
<h:panelGroup>
<h:inputText value="#{validationExemple.numeroSerie}" id="numeroSerie" required="true">
<f:validator validatorId="numeroDeSerie"/>
</h:inputText>
<h:message for="numeroSerie"/>
</h:panelGroup>
</h:panelGrid>
Validation
160
¨ Si on utilise l’annotation @FacesValidator, on peut ne pas utiliser le tag <validator> dans faces-config.xml
import java.util.ResourceBundle;
import java.util.regex.*;
import javax.faces.application.FacesMessage;
import javax.faces.component.*;
import javax.faces.context.FacesContext;
import javax.faces.validator.*;
@FacesValidator(value="NumeroDeSerie")
public class NumeroDeSerieValidator implements Validator {
public static final String CLE_MESSAGE = "message.validation.impossible";
@Override
public void validate(FacesContext contexte, UIComponent composant, Object objet) throws ValidatorException {
if ((contexte == null) || (composant == null)) throw new NullPointerException();
if (!(composant instanceof UIInput)) return;
Pattern p = Pattern.compile("[0-9][0-9]-[0-9][0-9][0-9]");
Matcher m = p.matcher(objet.toString());
if (!m.matches()) {
// final String baseName="resources.messagevalidation"; //baseName: The fully qualified name of the resource
bundle (<base-name> in <resource-bundle>).
// final ResourceBundle rb = ResourceBundle.getBundle(baseName, contexte.getViewRoot().getLocale());
final String varName="bundle1"; //varName: is the String representing the <var></var> in <resource-bundle>
final ResourceBundle rb = contexte.getApplication().getResourceBundle(contexte, varName);
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
rb.getString(CLE_MESSAGE), null));
}
}
}
Validation
161

¨ Pour internationaliser le traitement des messages, on peut utiliser:


¤ les objets messages du composants, qui sont des propriétés du composant avec
des valeurs par défaut. On remplit alors un fichier (eg " errorsvalidationconversion
_fr.properties") qu’on déclare dans le fichier de configuration faces-config.xml en
utilisant la balise <message-bundle> du tag <application> (L'exemple ci-dessous
suppose que le nom du fichier est errorsvalidationconversion.properties et qu'il
a été placé dans le package ressources):
<message-bundle>resources.errorsvalidationconversion</message-bundle>

<f:view locale="en_EN" /> <!--pour forcer le changement de la langue -->


<h:outputLabel for="name" value="Name:"/>
<h:inputText id="name" required="true">
<f:validateLength minimum="3" maximum="10"/>
</h:inputText>
<h:message for="name" /> <!--display a validation message -->
Validation
162

¤ Le fichier "errorsvalidationconversion _fr.properties" :


javax.faces.validator.LengthValidator.MAXIMUM = La longueur maximale du champ ''{1}'' est ''{0}''
javax.faces.validator.LengthValidator.MINIMUM = La longueur minimale du champ ''{1}'' est ''{0}''
javax.faces.component.UIInput.REQUIRED = {0}: valeur requise.

javax.faces.converter.DateTimeConverter.DATE = Veuillez saisir une date valide.


javax.faces.converter.DateTimeConverter.DATE_detail=Veuillez saisir une date valide. Exemple: {1}

javax.faces.converter.NumberConverter.NUMBER = Veuillez saisir un nombre.


javax.faces.converter.DoubleConverter.DOUBLE = {2}: ''{0}'' doit être un nombre entier ou décimal.
javax.faces.converter.DoubleConverter.DOUBLE_detail={2}: ''{0}'' doit être un nombre entier ou décimal. Exemple:10.5
javax.faces.converter.IntegerConverter.INTEGER = {2}: ''{0}'' doit être un entier.
javax.faces.converter.IntegerConverter.INTEGER_detail = {2}: ''{0}'' doit être un entier. Exemple: {1}

javax.faces.validator.LongRangeValidator.MAXIMUM = Le maximum autoris\u00E9 pour le champ ''{1}'' est ''{0}''


javax.faces.validator.LongRangeValidator.MINIMUM = Le champ ''{1}'' doit être supérieur ou égal à ''{0}''
javax.faces.validator.LongRangeValidator.NOT_IN_RANGE=Le champ''{2}'' doit \u00EAtre compris entre ''{0}’’ - ''{1}''
Validation
163
¨ Utiliser l'attribut title pour guider l’entrée de l’utilisateur
¨ Utiliser l'attribut label pour les composants d'entrée afin de supprimer l'ID client
(j_idt5: name : … ) du message d'erreur : (on aura : User name: message d’erreur)
<f:view locale="en_EN" /> <!--pour forcer le changement de la langue -->
<h:outputLabel for="name" value="Name:"/>
<h:inputText id="name" required="true" label="User name" title="Enter your name! ">
<f:validateLength minimum="3" maximum="10"/>
</h:inputText>
<h:message for="name" /> <!--display a validation message -->

Convertisseur Attribut Description


DoubleRangeValidator minimum Compare la valeur du composant aux valeurs minimales et
maximum maximales indiquées.
LengthValidator minimum, Teste le nombre de caractères de la valeur textuelle du
maximum composant.
LongRangeValidator minimum, Compare la valeur du composant aux valeurs minimales et
maximum maximales indiquées
RegexValidator pattern Compare la valeur du composant à une expression
régulière.
Validation personnalisée
164

¨ Si on veut valider un code postal ou une adresse de courrier


électronique, ou un num CIN.
¨ Dans ce cas, on doit créer notre propre validateur.
¨ Un validateur personnalisé est une classe qui doit implémenter
javax.faces.validator.Validator
¨ Elle possède la méthode:
¤ void validate(FacesContext context, UIComponent component, Object
value)
¨ Pour définir un validateur personnalisé dans JSF :
¤ Créer une classe de validation en implémentant l'interface
javax.faces.validator.Validator.
¤ Remplacer et redéfinir la méthode validate() .
¤ Attribuer un ID unique au validateur via l'annotation @FacesValidator(ID).
¤ Référencer la classe de validation personnalisée du composant JSF via la
balise <f:validator validatorId="ID" />.
Validation personnalisée
165

@FacesValidator(value = "isbnValidatorID")
public class IsbnValidator implements Validator {
private Pattern pattern;
private Matcher matcher;
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws
ValidatorException {

String componentValue = value.toString();


pattern = Pattern.compile("(?=[-0-9xX]{13}$)");
matcher = pattern.matcher(componentValue);
if (!matcher.find()) {
String message = MessageFormat.format("{0} is not a valid isbn format", componentValue);
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
throw new ValidatorException(facesMessage);
}
}
}

<h:inputText value="#{bean.isbn}" validator="isbnValidatorID"/>

ou bien :

<h:inputText value="#{bean.isbn}">
<f:validator validatorId="isbnValidatorID" />
</h:inputText>
Validation personnalisée
166
Gestion d’événements
167
¨ Lorsqu'un utilisateur clique sur un bouton ou un lien JSF ou modifie une valeur du
champ de texte, le composant d'interface utilisateur JSF déclenche un événement, qui
sera géré par le code de l'application.
¨ Pour gérer un tel événement, un gestionnaire d'événements doit être enregistré dans
le code d'application ou le bean géré.
¨ Lorsqu'un composant de l'interface utilisateur vérifie qu'un événement utilisateur s'est
produit, il crée une instance de la classe d'événements correspondante et l'ajoute à
une liste d'événements.
¨ Ensuite, Component déclenche l’événement, c’est-à-dire vérifie la liste des écouteurs
pour cet événement et appelle la méthode de notification d’événement sur chaque
écouteur ou gestionnaire.
¨ JSF fournit également des gestionnaires d'événements au niveau du système, qui
peuvent être utilisés pour effectuer certaines tâches au démarrage ou à l'arrêt de
l'application.
¨ Quelques gestionnaires d’événements importants dans JSF 2.0:
¤ valueChangeListener : Les événements de modification de valeur sont déclenchés lorsque
l'utilisateur apporte des modifications aux composants d'entrée.
¤ actionListener : Les événements d'action sont déclenchés lorsque l'utilisateur clique sur un
composant bouton ou lien.
Gestion d’événements
168

¨ ActionListener :
¤ soumission automatique du formulaire.
n déclenchement par :
n <h:commandButton value="..." .../>
n <h:commandButton image="..." .../>
n <h:commandLink .../>

¨ ValueChangeListener :
¤ soumission non automatique du formulaire (il faut utiliser une
méthode javascript).
n <h:selectOneMenu .../>
n <h:inputText .../>
n <h:selectBooleanCheckbox.../>
n <h:selectOneRadio .../>
Gestion d’événements :
actionListener
169

¨ Lorsque l'utilisateur interagit avec les composants, tels que


h: commandButton ou h: link, JSF déclenche des événements
d'action pouvant être gérés de deux manières:
¤ Méthode de liaison (binding) : Transmettre le nom de la
méthode du bean géré dans l'attribut actionListener de UI
Component.
¤ ActionListener : Implémenter l'interface ActionListener et
transmettre le nom de la classe d'implémentation à l'attribut
actionListener du composant UI.
Gestion d’événements :
actionListener
170

¨ Méthode de liaison (binding) :


¤ 1. Définir une méthode dans le bean « MyDataBean ».
@ManagedBean
@SessionScoped
public class MyDataBean{
private String data;
public String buttonId;
……
public void updateData(ActionEvent e) {
buttonId = event.getComponent().getClientId(); //Get submit button id
if (buttonId.equals("updateDataButton") ) {
data = "Hello World";
}
}
getters
setters

¤ 2. Utiliser cette méthode


<h:commandButton id = "updateDataButton"
value = "Submit" action = "Resultat"
actionListener = "#{myDataBean.updateData}" >
</h:commandButton>
Gestion d’événements :
actionListener
171

¨ Méthode ActionListener :
¤ 1. Implementer ActionListener
public class UserActionListener implements ActionListener {
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
// we can access MyDataBean directly
MyDataBean userDataBean = (MyDataBean) FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap().get("myDataBean");
userDataBean.setData("Hello World");
}
}

¤ 2. Utiliser la méthode d'écoute


<h:commandButton id = "submitButton" value = "Submit" action = "Resultat">
<f:actionListener type="nompackage.UserActionListener" />
</h:commandButton>
Gestion d’événements :
valueChangeListener
172

¨ Lorsque l'utilisateur interagit avec des composants d'entrée, tels


que h: inputText ou h: selectOneMenu, le JSF déclenche un
valueChangeEvent, qui peut être géré de deux manières:
¤ Méthode de liaison (binding) : Transmettre le nom de la méthode du
bean géré dans l'attribut valueChangeListener de UI Component.
¤ ValueChangeListener: Implémenter l'interface ValueChangeListener
et transmettre le nom de la classe d'implémentation à l'attribut
valueChangeListener du composant UI.
¨ En utilisant ValueChangeListener, le formulaire n’est pas
soumis automatiquement au contraire de ActionListener.
¨ Pour cela, on a besoin d’une méthode JavaScript
onclick="submit()" ou onchange="submit()"
Gestion d’événements :
valueChangeListener
173

¨ Méthode de liaison (binding) :


¤ 1. Définir une méthode dans le bean « MyDataBean ».
@ManagedBean(name = "myDataBean", eager = true)
@SessionScoped
public class MyDataBean implements Serializable {
private static final long serialVersionUID = 1L;
private static Map<String,String> countries;
private String selectedCountry = "United Kingdom"; //default value
static {
countries = new LinkedHashMap<String,String>();
countries.put("en", "United Kingdom"); //locale, country name
countries.put("fr", "French");
countries.put("de", "German");
}
public void localeChanged(ValueChangeEvent e) {
selectedCountry = e.getNewValue().toString(); //assign new value to country
}
getters & setters..

¤ 2. Utiliser cette méthode


<h:selectOneMenu value = "#{myDataBean.selectedCountry}" onchange = "submit()"
valueChangeListener = "#{myDataBean.localeChanged}" >
<f:selectItems value = "#{myDataBean.countries}" />
</h:selectOneMenu>
Gestion d’événements :
valueChangeListener
174

¨ Méthode valueChangeListener :
¤ 1. Implementer valueChangeListener
public class LocaleChangeListener implements ValueChangeListener {
@Override
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
// access MyDataBean bean directly
MyDataBean userDataBean = (MyDataBean ) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("myDataBean ");
userDataBean.setSelectedCountry(event.getNewValue().toString());
}
}

¤ 2. Utiliser la méthode d'écoute


<h:selectOneMenu value = "#{myDataBean.selectedCountry}" onchange = "submit()" >
<f:valueChangeListener type = "nompackage.LocaleChangeListener"/>
<f:selectItems value = "#{myDataBean.countries}" />
</h:selectOneMenu>
Gestion d’événements :
phaseListener
175
¨ phaseListener :
¤ 1. Implementer PhaseListener :
package controllers;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class MyPhaseListener implements PhaseListener {
private static final long serialVersionUID = 1L;
@Override
public void beforePhase(PhaseEvent pe) {
System.out.println("BEFORE Phase " + pe.getPhaseId());
}
@Override
public void afterPhase(PhaseEvent pe) {
System.out.println("AFTER Phase " + pe.getPhaseId());
}
@Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}
2. Utiliser la méthode d'écoute dans faces-config.xml
<lifecycle>
<phase-listener>controllers.MyPhaseListener</phase-listener>
</lifecycle>
Gestion d’événements : (Exercice)
176

¨ Créer un projet JSF contenant une page permettant le choix de langue par
l’utilisateur, et le nom de l’utilisateur en ajoutant PhaseListener:
Gestion d’événements : (Exercice)
177
Gestion d’événements : (Exercice)
178
Gestion d’événements : (Exercice)
179
Gestion d’événements : (Exercice)
180
Templates
181
¨ JSF fournit des balises spéciales pour créer une présentation commune pour une
application Web appelée balises facelets.
¨ Ces balises offrent la possibilité de gérer des parties communes de plusieurs pages
en un seul endroit.
¨ Pour ces balises, on doit utiliser le namespace suivants :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">

¨ Les templates (Les modèles) dans une application Web définissent une disposition et
un style d'interface communs.
¨ Par exemple, une même bannière, le même logo dans l’en-tête commun et les
informations de copyright dans le pied de page.
¨ JSF utilise les balises facelet suivantes pour fournir une disposition d'interface Web
standard:
¤ ui:insert : Utilisé dans le fichier de modèle. Il définit le contenu à placer dans un modèle.
La balise ui:define peut remplacer son contenu.
¤ ui:define : définit le contenu à insérer dans un modèle.
¤ ui:include : inclut le contenu d’une page xhtml dans une autre page xhtml.
¤ ui:composition : charge un modèle à l'aide de son attribut. Il peut également définir un
groupe de composants à insérer dans une page xhtml.
Templates : création
182
¨ Etapes à suivre pour créer un exemple de modèle:
¤ Étape 1: Créer un fichier d'en-tête: header.xhtml dans le dossier webapp → templates
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition>
<h1>Default Header</h1>
</ui:composition>
</body>

¤ Étape 2: Créer un fichier de pied de page: footer.xhtml dans le dossier webapp → templates
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition>
<h1>Default Footer </h1>
</ui:composition>
</body>
¤ Étape 3: Créer un fichier de contenu: contents.xhtml dans le dossier webapp → templates
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition>
<h1>Default Contents </h1>
</ui:composition>
</body>
Templates : création
183
¤ Étape 4: Créer un modèle: common.xhtml dans le dossier webapp → templates
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head></h:head>
<h:body>
<div style="border-width: 2px; border-color: green; border-style: solid;">
<ui:insert name="header">
<ui:include src="/templates/header.xhtml" />
</ui:insert>
</div>
<br />
<div style="border-width: 2px; border-color: black; border-style: solid;">
<ui:insert name="content">
<ui:include src="/templates/contents.xhtml" />
</ui:insert>
</div>
<br />
<div style="border-width: 2px; border-color: red; border-style: solid;">
<ui:insert name="footer">
<ui:include src="/templates/footer.xhtml" />
</ui:insert>
</div>
</h:body>
¤ Utiliser les balises ui: insert et ui: include pour inclure l'en-tête / pied de page et le fichier de contenu
dans le fichier modèle. Nommer chaque section dans ui: insert tag.
¤ l'attribut name de ui: insert tag sera utilisé pour remplacer le contenu de la section correspondante.
Templates : Usage
184

¤ Étape 5a: Utiliser le modèle avec un contenu par défaut: home1.xhtml


n Charger le modèle common.xhtml en utilisant la balise ui:composition dans
n’importe quelle page xhtml.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template = "common.xhtml">
</body>

¤ Étape 5b: Utiliser le modèle et définir son propre contenu: home2.xhtml


n Charger le modèle common.xhtml en utilisant la balise ui:composition dans
n’importe quelle page xhtml.
n Utiliser ui:define tag pour remplacer les valeurs par défaut du contenu.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="templates/common.xhtml">
<ui:define name="content">
<h:link value="Page 1" outcome="page1" />
&nbsp;
<h:link value="Page 2" outcome="page2" />
</ui:define>
</ui:composition>
</body>
Templates : paramètres
185
¨ En utilisant la balise ui:param, on peut passer des paramètres au fichier de modèle ou à un
fichier inclus.
¤ Paramètres vers une Section de la Template :
n Créer le paramètre dans : common.xhtml, en l’ajoutant à la balise ui:include.
n Utiliser la balise ui:param pour définir un paramètre contenant une valeur à transmettre à la section Header.
<ui:insert name = "header" >
<ui:include src = "/templates/header.xhtml" >
<ui:param name = "defaultHeader" value = "Default Header" />
</ui:include>
</ui:insert>
n Utilser le paramètre dans la page: header.xhtml
<ui:composition>
<h1>#{defaultHeader}</h1>
</ui:composition>
¤ Paramètres vers la Template :
n Créer le paramètre dans : home.xhtml, en l’ajoutant à la balise ui:composition.
n Utiliser la balise ui:param pour définir un paramètre contenant une valeur à transmettre à la section Header.

<ui:composition src = "/templates/common.xhtml" >


<ui:param name = "title" value = "Home" />
</ui: composition >

n Utilser le paramètre : common.xhtml


<h:body>
<h2>#{title}</h2>
</h:body>
Composents personnalisés
186

¨ JSF offre la possibilité de définir des composants


personnalisés, qui peuvent être utilisés pour rendre le
contenu personnalisé.
¨ on doit utiliser le namespace suivants :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite ="http://java.sun.com/jsf/composite "
>
Composents personnalisés : création
187
¨ Pour définir et créer un composant personnalisé dans JSF :
¤ Créer un dossier « resources » dans « src ».
¤ Créer un dossier « composants » dans le dossier « resources » puis créer un fichier
loginComponent.xhtml dans ce dossier avec un namespace de "composite".

<html xmlns = "http://www.w3.org/1999/xhtml"


xmlns:h = "http://java.sun.com/jsf/html"
xmlns:ui = "http://java.sun.com/jsf/facelets">
xmlns:tp = "http://java.sun.com/jsf/composite/dossier">

¨ Utiliser des balises composites pour créer le fichier: loginComponent.xhtml


¤ composite:interface : Indique les valeurs configurables à utiliser en composite:implementation.
¤ composite:attribute : Les valeurs de configuration sont déclarées à l'aide de cette balise.
¤ composite:implementation : Déclare le composant JSF. Peut accéder aux valeurs configurables
définies dans composite:interface à l'aide de l'expression # {cc.attrs.attribute-name}.
<composite:interface>
<composite:attribute name = "usernameLabel" />
<composite:attribute name = "usernameValue" />
</composite:interface>

<composite:implementation>
<h:form>
#{cc.attrs.usernameLabel} :
<h:inputText id = "username" value = "#{cc.attrs.usernameValue}" />
</h:form>
Composents personnalisés : usage
188

¨ Pour utiliser un composant personnalisé dans JSF :


¤ Créer un fichier xhtml et utiliser le namespace du composant personnalisé.
Le namespace sera "http://java.sun.com/jsf/dossier" où « dossier » est le
dossier du répertoire des ressources contenant le composant personnalisé.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:h = "http://java.sun.com/jsf/html"
xmlns:ui = "http://java.sun.com/jsf/facelets">
xmlns:tp = "http://java.sun.com/jsf/composite/dossier">

¤ Utiliser le composant personnalisé en tant que balise normale de JSF


et fournir les valeurs des paramètres.
<h:form>
<tp:loginComponent
usernameLabel = "Enter User Name: "
usernameValue = "#{userData.name}" />
</h:form>
Composents personnalisés (exercice)
189

¨ Créer et utiliser un composant personnalisé dans JSF :


Composents personnalisés (exercice)
190
Composents personnalisés (exercice)
191
Composents personnalisés (exercice)
192
Composents personnalisés (exercice)
193
AJAX et JSF
194

¨ AJAX signifie Asynchronous JavaScript and Xml.


¨ Ajax est une technique permettant d'utiliser HTTPXMLObject of
JavaScript pour envoyer et recevoir des données du serveur de
manière asynchrone. Ainsi, en utilisant la technique Ajax, le
code javascript échange des données avec le serveur, met à
jour des parties de la page Web sans recharger la page
entière.
¨ JSF fournit un support exceptionnel pour passer des appels
ajax. Il fournit la balise f: ajax pour gérer les appels ajax :

<f:ajax execute = "input-component-name" render = "output-component-name" />


AJAX et JSF
195

¨ Attributs de balise :
Attribut Description
Si true, le comportement Ajax sera appliqué à tout composant parent ou enfant. Si
disabled
false, le comportement Ajax sera désactivé.
L'événement qui appellera les requêtes Ajax, par exemple "click", "change", "blur",
Event
"keypress", etc.
Liste d'identifiants séparés par des espaces pour les composants à inclure dans la
Execute
requête Ajax.
Si "true", les événements générés à partir de ce comportement sont diffusés pendant
Immediate la phase "Apply Request" Values. Sinon, les événements seront diffusés lors de la
phase "Invoke Applications".
Expression EL pour une méthode dans un backing bean à appeler lors de la demande
Listener
Ajax.
Nom d'une fonction de rappel JavaScript qui sera appelée en cas d'erreur lors de la
Onerror
demande Ajax.
Nom d'une fonction de rappel JavaScript qui sera appelée pour gérer les événements
Onevent
de l'interface utilisateur.
Liste d'identifiants séparés par des espaces pour les composants qui seront mis à jour
Render
après une requête Ajax. Quelques valeurs spéciales : @this, @form, @none, & @all.
AJAX et JSF (Exemple)
196

¨ Code du bean NumberGenerator.java

package com.example.ajaxJSF;
import javax.faces.bean.ManagedBean;
@ManagedBean
public class NumberGenerator {
private double number = Math.random();
private double range = 1.0;
public double getRange() {
return (range);
}
public void setRange(double range) {
this.range = range;
}
public double getNumber() {
return (number);
}
public String randomize() {
number = range * Math.random();
return (null);
}
}
AJAX et JSF (Exemple)
197

¨ Code de la Facelets index.xhtml


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<h:title>hello ajax</h:title>
</h:head>
<h:body>
<h:form>
<fieldset>
<legend>Random Number</legend>
<h:commandButton value="Show Number" action="#{numberGenerator.randomize}">
<f:ajax render="numField1"/>
</h:commandButton>
<br />
<h2> <h:outputText value="#{numberGenerator.number}" id="numField1" /> </h2>
</fieldset>
</h:form>
</h:body>
</html>
AJAX et JSF (Exemple)
198

¨ Fichier web.xml

<?xml version="1.0" encoding="UTF-8"?>


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID"
version="3.1">
<display-name>ajaxJSF</display-name>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<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>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
AJAX et JSF (Exemple)
199

¨ Fichier faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
JSF et JDBC
200

¨ Comment intégrer JSF à une base de données via JDBC :


¤ 1. Prendre le pilote JDBC et copier-le dans le dossier lib du serveur.
¤ 2. Ajouter un fichier META-INF/context.xml à la racine de
l'application Web, qui définit les détails de connexion à la base de
données:
<Context>
<Resource name="jdbc/ENSASdb" auth="Container" type="javax.sql.DataSource"
maxActive="50" maxIdle="30" maxWait="10000"
username="yourUsername" password="yourPassword"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ENSASdb" />
</Context>
¤ 3. Dans le fichier de configuration web.xml, définir à nouveau la
source de données MySQL en ajoutant le tag suivant:
<resource-ref>
<description>MySQL Datasource example</description>
<res-ref-name>jdbc/ENSASdb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
JSF et JDBC
201

¨ Comment intégrer JSF à une base de données via JDBC :


¤ 4. Utiliser la source de données dans un managed bean :
n L'injection de ressources (@Resource) est le moyen le plus simple d'obtenir
la source de données :
@ManagedBean(name="customer")
@SessionScoped
public class CustomerBean implements Serializable {
//resource injection
@Resource(name="jdbc/ENSASdb")
private DataSource ds;
n On peut également obtenir la source de données via le service de
recherche de contexte :
@ManagedBean(name="customer")
@SessionScoped
public class CustomerBean implements Serializable {
private DataSource ds;
public CustomerBean(){
try {
Context ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ENSASdb");
} catch (NamingException e) { e.printStackTrace(); }
}
JSF et JDBC (Exercice)
202
JSF et JDBC (Exercice)
203
JSF et JDBC (Exercice)
204
JSF et JDBC (Exercice)
205
JSF et JDBC (Exercice)
206
JSF (Exercice)
207

¨ Jeu de nombre aléatoire


JSF (Exercice)
208
JSF (Exercice)
209
JSF (Exercice)
210
JSF (Exercice)
211
JSF (Exercice)
212
JSF (Exercice)
213
JSF (Exercice)
214
JSF (Exercice)
215
JSF (Exercice)
216

Vous aimerez peut-être aussi