Académique Documents
Professionnel Documents
Culture Documents
JAVA EE
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
¨ 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
¨ 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>
<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
@ManagedBean
public class Hello {
<h:head>
…
</h:head>
<h:body>
…
<h:form>
…
</h:form>
…
</h:body>
</html>
¨ 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
¨ 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
¨ 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
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
(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
¨ 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
¨ 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>
...
¨ 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>
¨ 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 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>
¤ 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
<f:view>
<h:outputText value="#{msg.my_message}"/>
</f:view>
¨ 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
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
¨ 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
¨ 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: 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
<h:selectOneMenu value="#{saisieOptions.taille}">
<f:selectItems value="#{saisieOptions.tailleItems}"/>
</h:selectOneMenu>
Composants JSF standard
122
<h:selectManyMenu value="#{saisieLegumes.legumes}">
<f:selectItems value="#{saisieLegumes.legumesItems}"/>
</h:selectManyMenu>
Composants JSF standard
123
<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
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
¨ 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)
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
Get Selected
Object
DataModel
¨ 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>
¨ Le fichier style.css :
.titre {
background-color:#000000;
color:#FFFFFF;
}
.paire {
background-color:#EFEFEF;
}
.impaire {
background-color:#CECECE;
}
Composants JSF standard
139
¨ Le passage de paramètres :
¤ Passer un paramètre: <f: param>
<h:outputLink value="index.jsp">
<h:outputText value="Index"/>
</h:outputLink>
¨ 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
¨ 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
}
¨ 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" />
¨ 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"/>
@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 {
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
¨ 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");
}
}
¨ 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());
}
}
¨ 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
<composite:implementation>
<h:form>
#{cc.attrs.usernameLabel} :
<h:inputText id = "username" value = "#{cc.attrs.usernameValue}" />
</h:form>
Composents personnalisés : usage
188
¨ 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
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
¨ Fichier web.xml
¨ 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