Vous êtes sur la page 1sur 23

Cours JSF/Java EE

30/11/2011

Remarque

INTRODUCTION JSF2
Adapt du cours de Richard Grin (grin@unice.fr)
Adaptation Michel Buffa (buffa@unice.fr), UNSA 2012

Ce support est une introduction JSF 2.0


utilis dans un cadre Java EE 6, avec un
serveur dapplications du type de Glassfish, et
CDI (Contexts and Dependency Injection)
activ dans les projets.

Version Richard Grin 1.2 du 30/11/11

21/10/99

Architecture typique dune application web

Crer des pages Web dynamiques avec des


composants construits sur le serveur

21/10/99

Conversion des donnes (tout est texte dans


linterface utilisateur)

Validation des donnes saisies par lutilisateur

Automatisation de laffichage des messages


derreur en cas de problmes de conversion
ou de validation
Richa.rd Grin

Richard Grin

JSF - page 4

Services rendus par JSF (2/2)

Permet de bien sparer linterface utilisateur,


la couche de persistance et les processus
mtier

21/10/99

JSF - page 2

Utilit de JSF

Services rendus par JSF (1/2)

Richard Grin

JSF - page 5

Internationalisation

Support dAjax sans programmation


javascript (communication en arrire-plan et
mise jour partielle de linterface utilisateur)

Fournit des composants standards pour


linterface utilisateur, puissants et faciles
utiliser

Possible dajouter ses propres composants

21/10/99

Richard Grin

JSF - page 6

Cours JSF/Java EE

30/11/2011

Standards

Page JSF

JSF 2.0 est intgr dans Java EE 6

JSF 2.0 peut (cest conseill) utiliser CDI


(Contexts and Dependency Injection)

21/10/99

Richard Grin

JSF - page 7

Les pages JSF contiennent des balises qui


dcrivent les composants qui reprsenteront
la page sur le serveur

21/10/99

Richard Grin

JSF - page 8

Une page JSF

Code XHTML qui contient des balises qui


dcrivent les composants sur le serveur

Sera traduit en XHTML pur pour tre envoy


au client Web

Architecture des applications JSF

Contient des parties en EL : #{}

Utilise souvent une (ou plusieurs) bibliothque de


composants (PrimeFaces ou RichFaces par
21/10/99
Richard Grin
JSF - page 9
exemple)

Composants de larchitecture

21/10/99

Les pages JSF sont utilises pour linterface


avec lutilisateur ; elles ne contiennent pas de
traitements (pas de code Java ou autre code
comme dans les pages JSP)

Les backing beans font linterface entre les


pages JSF et le reste de lapplication

Ces backing beans peuvent effectuer les


traitements lis directement linterface
utilisateur ; ils font appels des EJB ou des
classes Java ordinaires pour effectuer les autres
traitements

des pages JSF


des backing beans
des EJB
des entits
des classes Java ordinaires

Richard Grin

JSF - page 10

Rpartition des tches (1/2)

Dans larchitecture des applications qui


utilisent JSF

21/10/99

Richard Grin

JSF - page 11

Cours JSF/Java EE

30/11/2011

Rpartition des tches (2/2)

Backing bean

Les EJB sont chargs des traitements mtier


et des accs aux bases de donnes

Les accs aux bases de donnes utilisent JPA


et donc les entits

Souvent, mais pas obligatoirement, un backing


bean par page JSF

Un backing bean fournit du code Java pour


linterface graphique

21/10/99

Backing bean

Richard Grin

JSF - page 14

Container pour les JSF

Le traitement peut tre exclusivement li


linterface graphique (par exemple si un
composant nest visible que si lutilisateur a
choisi une certaine valeur) ; dans ce cas le
backing bean intervient seul
Sinon le backing bean fait appel des EJB ou
quelquefois des classes Java ordinaires

Remarque importante : un EJB doit tre


totalement indpendant de linterface
graphique ; il excute les processus mtier ou
soccupe de la
persistance des donnes
21/10/99
Richard Grin
JSF - page 15

Pour quil sache traiter les pages JSF, le


serveur Web doit disposer dun container JSF

On peut utiliser pour cela un serveur


dapplications du type de Glassfish ou
quivalent

21/10/99

Richard Grin

JSF - page 16

Composants JSF sur le serveur

JSF utilise des composants ct serveur pour


construire la page Web

Par exemple, un composant java UIInputText


du serveur sera reprsent par une balise
<INPUT> dans la page XHTML

Une page Web sera reprsente par une vue,


UIViewRoot, hirarchie de composants JSF qui
reflte la hirarchie de balises HTML

21/10/99

Richard Grin

JSF - page 17

Le cycle de vie

21/10/99

Richard Grin

JSF - page 18

Cours JSF/Java EE

30/11/2011

Cycle de vie JSF 2

Le servlet Faces

Pour bien comprendre JSF il est indispensable


de bien comprendre tout le processus qui se
droule entre le remplissage dun formulaire
par lutilisateur et la rponse du serveur sous la
forme de laffichage dune nouvelle page.

21/10/99

Richard Grin

JSF - page 19

URL des pages JSF


Les pages JSF sont traites par le servlet parce
que le fichier web.xml contient une
configuration telle que celle-ci :

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>

Le pattern peut aussi tre de la forme


*.faces ou *.jsf

Richard Grin

Toutes les requtes vers des pages JSF


sont interceptes par un servlet dfini dans le
fichier web.xml de lapplication Web

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>
javax.faces.webapp.FacesServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

21/10/99

Richard Grin

JSF - page 20

Codage - dcodage

21/10/99

JSF - page 21

Les pages HTML renvoyes par une


application JSF sont reprsentes par la vue,
arbre de composants Java

Lencodage est la gnration dune page


HTML partir de larbre des composants

Le dcodage est lutilisation des valeurs


renvoyes par un POST HTML pour donner
des valeurs aux variables dinstance des
composants Java, et le lancement des actions
associes aux UICommand JSF (boutons
ou liens)
21/10/99
Richard Grin
JSF - page 22

Cycle de vie

Le codage/dcodage fait partie du cycle de


vie des pages JSF,

Le cycle de vie est compos de 6 phases,

Ces phases sont gres par le servlet


Faces qui est activ lorsquune requte
demande une page JSF

21/10/99

Richard Grin

JSF - page 23

pas compltement
vident !

21/10/99

Richard Grin

JSF - page 24

Cours JSF/Java EE

30/11/2011

La vue

Demande page HTML

Etudions tout dabord le cas simple dune


requte GET dun client qui demande
laffichage dune page JSF

21/10/99

Richard Grin

JSF - page 25

Contenu de la vue

Cette requte HTTP est intercepte par le


servlet Faces,

La page HTML correspondant la page JSF doit


tre affiche la suite de cette requte HTTP

La page HTML qui sera affiche est reprsente


sur le serveur par une vue

Cette vue va tre construite sur le serveur et


transforme sur le serveur en une page HTML
qui sera envoye au client

21/10/99

Richard Grin

JSF - page 26

Construction vue

Cette vue est un arbre dont les lments sont


des composants JSF qui sont sur le serveur
(des instances de classes qui hritent de
UIComponent),

Une vue forme des composants JSF est donc


construite sur le serveur (ou restaure si elle
avait dj t affiche) :
phase Restore View

Sa racine est de la classe UIViewRoot

La vue sera conserve sur le serveur pour le


cas o on en aurait encore besoin

21/10/99

Richard Grin

JSF - page 27

Richard Grin

JSF - page 28

Traitement dun formulaire

Rendu de la page HTML

21/10/99

Puisquil ny a pas de donnes ou


dvnements traiter, la vue est
immdiatement rendue : le code HTML est
construit partir des composants de la vue et
envoy au client :
phase Render Response

Nous allons cette fois-ci partir dune requte


HTTP gnre partir dune page HTML qui
contient un formulaire

Lutilisateur a saisi des valeurs dans ce


formulaire

Ces valeurs sont passes comme des


paramtres de la requte HTTP ; par exemple,
http://machine/page.xhtml?nom=bibi&preno
m=bob

si la requte est une requte GET, ou dans le


corps dun POST
21/10/99

Richard Grin

JSF - page 29

21/10/99

Richard Grin

JSF - page 30

Cours JSF/Java EE

30/11/2011

Phase de restauration de la vue

21/10/99

Richard Grin

JSF - page 31

La vue qui correspond la page qui contient


le formulaire est restaure (phase Restore
View )

Tous les composants reoivent la valeur


quils avaient avant les nouvelles saisies de
lutilisateur

21/10/99

Richard Grin

JSF - page 32

Phase dapplication des paramtres

21/10/99

Richard Grin

JSF - page 33

Tous les composants Java de larbre des


composants reoivent les valeurs qui les
concernent dans les paramtres de la requte
HTTP : phase Apply Request Values

Par exemple, si le composant texte dun


formulaire contient un nom, le composant Java
associ conserve ce nom dans une variable

En fait, chaque composant de la vue rcupre


ses propres paramtres dans la requte HTTP

21/10/99

Richard Grin

JSF - page 34

Phase de validation

21/10/99

Richard Grin

JSF - page 35

Les donnes traites ltape prcdentes


sont converties dans le bon type Java

Elles sont aussi valides (par exemple, si un


ge doit tre compris entre 18 et 65)

Si une validation choue, la main est donne


la phase de rendu de la rponse

21/10/99

Richard Grin

JSF - page 36

Cours JSF/Java EE

30/11/2011

Phase de validation

Comment cest fait : chaque composant valide


et convertit les donnes quil contient

Si un composant dtecte une valeur non


valable, il met sa proprit valid false et il
met un message derreur dans la file dattente
des messages (ils seront affichs lors de la
phase de rendu render response ) et les
phases suivantes sont sautes

21/10/99

Richard Grin

JSF - page 37

21/10/99

Richard Grin

JSF - page 38

21/10/99

Richard Grin

JSF - page 40

21/10/99

Richard Grin

JSF - page 42

Phase de mise jour du modle

Si les donnes ont t valides, elles sont


mises dans les proprits des Java beans
associes aux composants de larbre des
composants

Exemple :
<h:inputText id="nom"
value="#{backingBean.utilisateur.nom}" />

21/10/99

Richard Grin

JSF - page 39

Phase dinvocation de lapplication

Les actions associes aux boutons ou aux


liens sont excutes

Le plus souvent le lancement des processus


mtier se fait par ces actions

La valeur de retour de ces actions va


dterminer la prochaine page afficher
(navigation)

21/10/99

Richard Grin

JSF - page 41

Cours JSF/Java EE

30/11/2011

Phase de rendu de la rponse

Sauter des phases

La page dtermine par la navigation est


encode en HTML et envoye vers le client
HTTP

21/10/99

Richard Grin

Cet attribut peut tre ajout un bouton ou


un lien (<h:commandButton>,
<h:commandLink>, <h:button> et <h:link>)
pour faire passer immdiatement de la phase
Apply request values la phase Invoke
Application (en sautant donc les phases de
validation et de mise jour du modle),

Par exemple, si lutilisateur clique sur un


bouton dannulation, on ne veut pas que la
validation des champs de saisie soit
effectue, ni que les valeurs actuelles soient
mises dans le modle

Autre exemple : si on gnre un fichier PDF


renvoyer lutilisateur et quon lenvoie
lutilisateur directement sur le flot de sortie de
la rponse HTTP, on ne veut pas que la
phase de rendu habituelle soit excute

immediate=true sur un EditableValueHolder

Cet attribut peut tre ajout un champ de


saisie, une liste droulante ou des botes
cocher pour dclencher immdiatement la
validation et la conversion de la valeur quil
contient, avant la validation et la conversion
des autres composants de la page

Utile pour effectuer des modifications sur


linterface utilisateur sans valider toutes les
valeurs du formulaire

Exemple : un bouton dannulation dun


formulaire.

Exemple (1/2)

Il est quelquefois indispensable de sauter des


phases du cycle de vie

JSF - page 43

immediate=true sur un UICommand

Formulaire qui contient champ de saisie du


code postal et un champ de saisie de la ville,
Lorsque le code postal est saisi, un
ValueChangeListener met automatiquement
jour la ville :

Exemple (2/2)

La solution est de mettre un


immediate=true sur le champ code postal.

<h:inputText valueChangeListener="#{}"
...
onChange = "this.form.submit()" />

La soumission du formulaire dclenche par


la modification du code postal ne doit pas
lancer la validation de tous les composants
du formulaire qui ne sont peut-tre pas
encore saisis

Cours JSF/Java EE

30/11/2011

Handler de navigation

La navigation entre les pages indique quelle


page est affiche quand lutilisateur clique sur
un bouton pour soumettre un formulaire ou sur
un lien

La navigation peut tre dfinie par des rgles


dans le fichier de configuration facesconfig.xml ou par des valeurs crites dans le
code Java ou dans la page JSF

Navigation entre pages JSF

21/10/99

Richard Grin

JSF - page 49

Navigation statique et dynamique

La navigation peut tre statique : dfinie en


dur au moment de lcriture de lapplication

La navigation peut aussi tre dynamique :


dfinie par ltat de lapplication au moment
de lexcution (en fait, par la valeur retourne
par une mthode)

21/10/99

Richard Grin

JSF - page 50

Dans les pages JSF

Dans les pages JSF on indique la valeur ou la


mthode associe un bouton qui dterminera
la navigation.

Avec une valeur :


<h:commandButton value="Texte du bouton"
action= "pageSuivante"/>

Avec une mthode (qui retourne un nom de


page) :
<h:commandButton value="Texte du bouton"
action="#{nomBean.nomMethode}"/>

21/10/99

Richard Grin

JSF - page 51

21/10/99

Richard Grin

JSF - page 52

Dans le fichier de configuration facesconfig.xml


<navigation-rule>
<from-view-id>/index.xhtml</from-view-id>
<navigation-case>

Valeur retourne

<from-outcome>succes</from-outcome>
<to-view-id>/succes.xhtml</to-view-id>
<navigation-case>

Managed Beans / Backing Beans


Classes pour soutenir les pages JSF

<navigation-case>
Michel Buffa (buffa@unice.fr), UNSA 2012

<from-outcome>echec</from-outcome>
<to-view-id>/echec.xhtml</to-view-id>
<navigation-case>
</navigation-rule>
21/10/99

Richard Grin

JSF - page 53

Cours JSF/Java EE

Plan de la section

Le contenu des beans dans JSF :

30/11/2011

Les composantes des beans grs

Des getters/setters qui correspondent aux <input/> de


formulaires (quon appelle proprits), avec, le plus souvent
les variables correspondantes
Des mthodes action par ex : verifieLoginPassword()
Des mthodes listener, des mthodes pour convertir et valider

Les portes des beans

Comment pr-remplir les champs des formulaires

Des proprits pour les donnes rsultat

Un exemple simple (1)

Scnario

Entrer le login dun client et son password,


Afficher en rsultat :
Une page affichant son nom, prnom et solde de
son compte bancaire,
3 pages diffrentes selon la valeur du solde,
La

page initiale avec des messages derreur si le


formulaire a t mal rempli (donnes
manquantes ou incorrectes), ou une page
derreur

Le container JSF gre le bean

Il linstancie automatiquement,
Ncessit davoir un constructeur par dfaut
Contrle son cycle de vie
Ce cycle dpend de la porte (scope) (request, session,
application, etc.)
Appelle les mthodes setter
Par ex pour <h:inputText value="#{customer.firstName"/>,
lorsque le formulaire est soumis, le paramtre est pass
setFirstName()
Appelle les mthodes getter
#{customer.firstName} revient appeler getFirstName()

Seront initialises par les mthodes action aprs


un traitement mtier,
Il faut au moins une mthode get sur la proprit
afin que les donnes puissent tre affiches dans
une page de rsultat.

Des mthodes diverses pour couter des


vnements (par exemple un changement de
valeur dans un champ input), convertir et
valider

Une par bouton de soumission dans le formulaire


La mthode sera appele lors du clic sur le bouton
par JSF

Caractristiques des Beans grs

Une paire pour chaque lment input de formulaire,


Les setters sont automatiquement appels par JSF
lorsque le formulaire sera soumis.

Des mthodes action

Notamment les champs <input../> et les menus/listes


droulantes

Les composantes des beans grs

Des proprits (dfinies par des get/set ou


is)

Dclaration par @ManagedBean avant la classe, ou


par @Name si CDI

Un exemple simple (2)

De quoi a besoin le bean gr ?

Proprits correspondant aux lments du


formulaire dentre : ex
getCustomerLogin/setCustomerLogin, etc.
Mthode action :
Pour rcuprer un Customer partir du login.
De quoi stocker les rsultats
Stocker le Customer rsultat dans une variable
dinstance, initialement vide, avec get/set
associs

10

Cours JSF/Java EE

30/11/2011

BanqueMBean partie 1 : proprits pour


les lments de formulaire
@ManagedBean
public class BanqueMBean {
private String customerLogin, password;
Appel par JSF lors de
laffichage du formulaire,
comme la variable vaut null au dpart
le champs sera vide.

public String getCustomerLogin() {


return customerLogin;
}

BanqueMBean partie 2 : mthodes


action
@Named
public class BanqueMBean {
private String customerLogin, password;
private Customer customer;
// ici get/set pour login, password, et customer
public String checkConnexion() {
customer =
customerManager.checkLoginPassword(
customerLogin, password);
if(customer != null) {
return "bienvenue";
} else {
return null; // affiche la mme page
}

public void setCustomerLogin(String customerLogin) {


this.customerLogin = customerLogin;
}
Lors de la soumission, le bean, est instanci
public String getPassword() {
return password;
}

nouveau (puisquil est RequestScoped par


dfaut), et la valeur dans le formulaire est
passe cette mthode

public void setPassword(String password) {


this.password = password;
get et setPassword sont identiques get et
setCustomerLogin, part quon ne peut
}

}
}

pr-remplir un champ password (interdit par


les navigateurs), donc getPassword ne sera
pas appel initialement

Nom dun bean (version CDI)

Nom dun bean (version JSF)

@Named
public class BanqueMBean {

@ManagedBean
public class BanqueMBean {

Par dfaut cest le nom de la classe avec une


minuscule au dbut : banqueMBean

Par dfaut cest le nom de la classe avec une


minuscule au dbut : banqueMBean

Pour donner un autre nom :

Pour donner un autre nom :

@Named("banqueController")
public class BanqueMBean {

Cration dun backing bean

@ManagedBean(name="banqueController")
public class BanqueMBean {

La porte dun backing bean

Indique la dure de vie du backing bean

Quand une page JSF fait rfrence un bean,


par exemple

La dure de vie dun bean dpend de sa


porte

Par exemple un bean de porte Request sera


supprim lorsque la requte en cours sera
termine

Les beans CDI et les beans JSF ont


plusieurs portes en commun et quelques
portes particulires

<h:inputText id="nom"
value="#{backingBean.utilisateur.nom}" />

le container JSF regarde si une instance de la


classe existe dj

Si une instance est trouve, elle est utilise

Sinon, une nouvelle instance est cre par le


container

11

Cours JSF/Java EE

Les diffrentes portes

Valeurs communes CDI et JSF : request,


session, application

Valeurs particulires CDI : conversation,


dependant

Valeurs particulires JSF : view, none ou


custom

RequestScope = valeur par dfaut.

On les spcifie avec des annotations


(recommand) ou dans faces-config.xml

Annotations pour les Scopes

@SessionScoped

30/11/2011

Annotations pour les Scopes

On cre une nouvelle instance du bean pour


chaque requte.
Puisque les beans sont aussi utiliss pour initialiser
des valeurs de formulaire, ceci signifie quils sont
donc gnralement instancis deux fois (une
premire fois laffichage du formulaire, une
seconde lors de la soumission)
Ceci peut poser des problmes

Annotations pour les Scopes

@ViewScoped

La mme instance est utilise aussi souvent que le


mme utilisateur reste sur la mme page, mme sil
fait un refresh (reload) de la page !
Le bean doit tre srialisable,
Convient bien pour les pages JSF faisant des
appels Ajax (une requte ajax = une requte HTTP
=> une instance si on est en RequestScoped !)

@ApplicationScoped

On cre une instance du bean et elle durera le


temps de la session. Le bean doit tre Srialisable.
Utile par exemple pour grer le statut
connect/non connect dun formulaire
login/password.
On utilisera les attributs render des lments de
UI pour afficher telle ou telle partie des pages selon
les valeurs des variables de session.
Attention ne pas abuser du SessionScoped,
piges possibles avec les variables caches ou les
ditions de donnes multiples (cf tp1)

Annotations pour les Scopes

@RequestScoped

Met le bean dans lapplication , linstance sera


partage par tous les utilisateurs de toutes les
sessions.
Pour des mthodes utilitaires ou pour mettre en
cache des informations qui ne doivent pas varier
(liste des pays par exemple).

Annotations pour les Scopes

@ConversationScoped

Utilise CDI, ne fait pas partie de JSF, @Named


obligatoire (pas @ManagedBean)
Semblable aux session mais dure de vie gre
par programme ,
Utile pour faire des wizards ou des formulaires
remplis partiellement au travers de plusieurs pages;
On va confier une variable injecte le dmarrage
et la fin de la dure de vie du bean,

12

Cours JSF/Java EE

Ou placer ces annotations

@SessionScoped

Aprs @Named ou @ManagedBean en gnral,

30/11/2011

Ide : gestionnaire login password. Si


lutilisateur se trompe de password on raffiche
le champs login rempli, sinon on dirige vers la
page daccueil et on mmorise dans une
variable le fait quon est authentifi.

Backing Bean :

Named recommand si on a le choix.

Attention aux imports !!!!!

Si @ManagedBean (JSF), alors les scopes doivent


venir du package javax.faces.bean
Si @Named (CDI) les scopes doivent venir de
javax.enterprise.context
Cas particuliers : ConversationScoped que dans
javax.enterprise.context donc utilis avec @Named, et
ViewScoped vient de javax.faces.bean donc utilis
avec @ManagedBean

Srializable

@SessionScoped, page JSF


login/password
<h:outputText rendered="#{!loginMBean.connected}"
value="#{loginMBean.message}" />

<h:form id="deconnexionForm"
rendered="#{loginMBean.connected}">

<h:form id="loginForm"
rendered="#{!loginMBean.connected}">

<h:outputText
value="#{loginMBean.message}" />

Username: <h:inputText id="loginForm"


value="#{loginMBean.login}" />

<h:commandButton value="Deconnexion"
action="#{loginMBean.deconnexion}" />

Username: <h:inputText id="password"


value="#{loginMBean.password}" />

</h:form>

<h:commandButton value="Login"
action="#{loginMBean.connexion}" />
</h:form>

suite transparents suivant !

@SessionScoped, page JSF


login/password
@Named(value = "loginMBean")
@SessionScoped
public class LoginMBean implements Serializable {
private
private
private
private

String login;
String password;
boolean connected = false;
String message = "Veuillez vous identifier :";

Note : lattribut rendered remplace les if/then/else de


JSTL !

SessionScoped, page JSF login/password


public void deconnexion() {
connected = false;
message = "Veuillez vous identifier :";
}
public void connexion() {
connected = (login.equals("michel")
&& password.equals("toto"));

public boolean isConnected() {


return connected;

if (connected) {
}
message = "Bienvenue, vous tes connect en tant que "
+ login + " ! ";
} else {
message = "Mauvais login/password, recommencez";

}
}

13

Cours JSF/Java EE

30/11/2011

@ViewScoped

@ConversationScoped
@Named(value = "customerMBean")
@ConversationScoped
public class CustomerMBean implements Serializable {
@Inject

private Conversation conversation;

Prvu pour les pages faisant des appels Ajax,

Pas de nouvelle instance tant quon est dans la


mme page JSF
La navigation doit renvoyer null ; toute autre valeur,
mme dsignant la mme page, efface les donnes
de la vue

public String showDetails(Customer customer) {


this.customer = customer;
conversation.begin();
return "CustomerDetails?id=" +
customer.getCustomerId() +
"&faces-redirect=true";
}
public String update() {
customer = customerManager.update(customer);
conversation.end();
return "CustomerList?faces-redirect=true";
}

@ConversationScoped

Danger : chaque begin() doit correspondre


un end()

Attention avec des pages qui sont


bookmarkables (correction tp1 par ex, le
formulaire est bookmarkable) et appelables de
plusieurs manires,
Pige avec les vnements preRenderView : la
mthode appele doit faire un begin et il faut faire
un end quand on sort du formulaire, mais comme la
page peut tre aussi invoque depuis une autre
page, il ne faut pas faire un begin avant le
preRenderView
conversation.isTransient() peut aider

Modle de navigation GET - PRG

21/10/99

Navigation par dfaut


Par dfaut, JSF travaille avec des requtes
POST

Depuis JSF 2.0 il est aussi devenu simple de


travailler avec des requtes GET, ce qui facilite
lutilisation des marque-pages (bookmarks) et
de lhistorique des navigateurs et vite des
doubles validations de formulaire non voulues
par lutilisateur

Richard Grin

JSF - page 82

Utiliser GET

21/10/99

Richard Grin

2 composants de JSF 2.0 permettent de


gnrer des requtes GET : <h:button> et
<h:link>

JSF - page 83

14

Cours JSF/Java EE

30/11/2011

Le problme avec POST

La raison du problme

Avec une requte POST envoye pour


soumettre un formulaire
le refresh de la page affiche (ou un retour
en arrire) aprs un POST soumet
nouveau le formulaire,
ladresse de la page affiche aprs le
POST est la mme que celle du formulaire
(donc pas possible de faire rafficher cette
page en utilisant lhistorique du navigateur)

Les consquences du problme

Le navigateur est en retard dune page pour


afficher lURL de la page en cours

Il ne garde donc pas la bonne adresse URL si


lutilisateur veut garder un marque-page

Le navigateur pense tre toujours dans la page


qui contient le formulaire aprs un retour en
arrire ou un refresh et il essaie de le
soumettre nouveau (il demande malgr tout
une confirmation lors de la soumission multiple
dun formulaire)

Cest le servlet JSF qui redirige vers la page


dsigne par le modle de navigation JSF

Le navigateur na pas connaissance de cette


direction et pense tre toujours dans la page
qui contient le formulaire qui a t soumis

La solution :
POST, REDIRECT, GET (PRG)

Le modle POST REDIRECT GET


prconise de
Ne jamais montrer une page en rponse
un POST,
Charger les pages uniquement avec des
GET,
Utiliser la redirection pour passer de POST
GET.

21/10/99

Sans PRG

21/10/99

Richard Grin

JSF - page 88

Richard Grin

JSF - page 90

Avec PRG

Richard Grin

JSF - page 89

21/10/99

15

Cours JSF/Java EE

30/11/2011

Problme de PRG

Solutions

PRG peut poser un problme lorsque la page


vers laquelle lutilisateur est redirige (le GET)
doit afficher des donnes manipules par le
formulaire
Exemple : page qui confirme lenregistrement
dans une base de donnes des informations
saisies par lutilisateur dans le formulaire

En effet, si les informations sont conserves


dans un bean de porte requte de la page du
formulaire, elles ne sont plus disponibles aprs
la redirection Richard Grin
21/10/99
JSF - page 91

Paramtres de vue

<f:metadata>
<f:viewParam name="n1"
value="#{bean1.p1}" />
<f:viewParam name="n2"
value="#{bean2.p2}" />
<f:metadata>
Richard Grin

JSF - page 93

<f:viewParam> (suite)

Une des solutions est de ranger les informations


dans la session plutt que dans la requte

Cependant cette solution peut conduire une


session trop encombre

Une autre solution est de passer les informations


dune requte lautre

JSF 2.0 offre 3 nouvelles possibilits qui


facilitent la tche du dveloppeur :
la mmoire flash,
les paramtres de vue,
21/10/99
Richard Grin
JSF - page 92
La porte conversation de CDI

<f:viewParam>

Les paramtres dune vue sont dfinis par des


balises <f:viewParam> incluses dans une
balise <f:metadata> ( placer au dbut de la
page destination de la navigation, avant les
<h:head> et <h:body>) :

21/10/99

Un URL vers une page qui contient des balises


<f:viewParam> contiendra tous les
paramtres indiqus par les <f:viewParam>
sil contient includeViewParams=true

Lattribut name dsigne le nom dun paramtre


HTTP de requte GET

Lattribut value dsigne (par une expression du


langage EL) le nom dune proprit dun bean
dans laquelle la valeur du paramtre est
range

Important : il est possible dindiquer une


conversion ou une validation faire sur les
paramtres, comme sur les valeurs des
composants saisis par lutilisateur.

21/10/99

JSF - page 94

Fonctionnement de includeViewParams
1.

La page de dpart a un URL qui a le


paramtre includeViewParams

2.

Elle va chercher les <f:viewParam> de la


page de destination. Pour chacun, elle
ajoute un paramtre la requte GET en
allant chercher la valeur qui est indique par
lattribut value du <f:viewParam>

3.

A larrive dans la page cible, la valeur du


paramtre est mise dans la proprit du
bean indique par lattribut value

Exemple :
<h:commandButton value=
action="page2?faces-redirect=true
&amp;includeViewParams=true"
Dans le navigateur on verra lURL avec
les paramtres HTTP.

Richard Grin

16

Cours JSF/Java EE

30/11/2011

Fonctionnement de includeViewParams

Cela revient faire passer une valeur dune


page lautre

Si la porte du bean est la requte et quil y a


eu redirection, cela revient plus prcisment
faire passer la valeur dune proprit dun
bean dans un autre bean du mme type

Donner une valeur un paramtre

Il y a plusieurs faons de donner une valeur


un paramtre de requte GET ; les voici dans
lordre de priorit inverse (la dernire faon
lemporte)

Dans la valeur du outcome


<h:link outcome="page?p=4&amp;p2=bibi " >
<h:link outcome="page?p=#{bean.prop + 2} " >
Avec les paramtres de vue
<h:link outcome="page"
includeViewParams="true" >
Avec un <f:param>
<h:link outcome="page" >
<f:param name="p" value=/>
</h:link>

Fonctionnement

Exemple ; page2.xhtml
<!DOCTYPE >
<html xmlns="http://www.w3.org/1999/xhtml"

Si page2 est appel par la requte GET


suivante,
page2.xhtml?param1=v1&param2=v2
la mthode setProp1 du bean est appele
avec largument v1 (idem pour param2 et v2),

Si un paramtre napparait pas dans le GET, la


valeur du paramtre de requte est null et le
setter nest pas appel (la proprit du bean
nest donc pas mise null).

xmlns=...>
<f:metadata>
<f:viewParam name="param1"
value="#{bean.prop1}"/>
<f:viewParam name="param2" value="#{}"/>
</f:metadata>
<h:head></h:head>
<h:body>
Valeur : #{bean.prop1}
21/10/99

Richard Grin

JSF - page 99

Bookmarquer des URL de page

Outre le fait quun refresh ne provoque plus de


soumission du formulaire, le modle PRG
permet aussi de permettre de conserver un
URL utile dans un marque-page ou dans
lhistorique
En effet, lURL contient les paramtres qui
permettront de rafficher les mmes donnes
un autre moment
Sans PRG, les donnes utiles sont conserves
dans lentit de la requte et pas dans lURL

21/10/99

Richard Grin

JSF - page 101

21/10/99

Richard Grin

JSF - page 100

preRenderView Listener (1)

Une situation courante : il est possible de ne


mettre en paramtre quun identificateur des
donnes qui ont t traites

Par exemple, que la cl primaire des donnes


enregistres dans la base de donnes

Avec les procds prcdents on peut faire


passer cet identificateur dans la page qui va
afficher les donnes

21/10/99

Richard Grin

JSF - page 102

17

Cours JSF/Java EE

30/11/2011

preRenderView Listener (2)

Exemple de preRenderView

Mais a ne suffit pas ; il faut utiliser une autre


nouveaut de JSF 2.0, les listeners
preRenderView qui permet dexcuter une
action avant laffichage de la vue
On peut ainsi aller rechercher (par exemple
dans une base de donnes) les informations
identifies par lidentificateur depuis la vue
Pour le GET, le code du listener joue en
quelque sorte le rle de laction pour un POST

21/10/99

Richard Grin

JSF - page 103

<f:metadata>
<f:viewParam name="id"
value="#{bean.IdClient}"/>
<f:event type="preRenderView"
listener="#{bean.chargeClient}"/>
</f:metadata>
...
Nom : #{bean.client.nom}
...
21/10/99

Richard Grin

JSF - page 104

Attributs communs aux composants

id donne un identifiant au composant

rendered indique si le composant doit tre


affich (la valeur est le plus souvent le rsultat
boolen dune mthode Java du backing bean,
donn par une expression EL)

styleClass donne le nom de la classe CSS


pour la mise en forme du composant

binding permet de lier le composant une


proprit dun backing bean (classe Java)

ANNEXES

R. Grin

Attribut binding
Le composant peut ainsi tre manipul par le
backing bean avec du code Java

On nutilise cet attribut que pour des


traitements spciaux, comme, par exemple, lier
une dataTable pour pouvoir rcuprer la ligne
en cours par la mthode Java
table.getRowData()

JSF

page 106

Messages dinformation ou derreur

R. Grin

JSF

page 107

Les messages derreur lis JSF, gnrs par


JSF ou par le code Java sont affichs

dans une zone de la page rserve aux messages


ou prs du composant qui a gnr lerreur

Exemples de messages :

indique que la saisie de lutilisateur a provoqu une


erreur de conversion ou de validation
message gnr par le code Java pour une raison
quelconque

R. Grin

JSF

page 108

18

Cours JSF/Java EE

30/11/2011

<h:messages>

<h:message>

Rserve un endroit de la page pour afficher


tous les messages pour tous les composants
et les messages qui ne sont pas lis un
composant particulier

De nombreux attributs permettent de dfinir le


style CSS et la mise en page et dindiquer si on
veut seulement un rsum ou les dtails du
message

Exemple :
<h:messages errorClass="erreur" />

R. Grin

JSF

page 109

Un attribut obligatoire for indique lidentificateur


du composant qui est li ce message

Habituellement plac prs du composant dans


la page JSF

Exemple :
<h:message for="nom" />

R. Grin

JSF

page 110

Les listes

Annexe sur les listes droulantes

Il y a plusieurs composants JSF standards qui


permettent de proposer un choix (ou plusieurs)
parmi une liste de valeurs

Tous les composants sont btis sur des


classes Java communes mais se prsentent
diffremment lutilisateur

R. Grin

Listes choix unique


Boutons radios avec <h:selectOneRadio>

Liste droulante avec <h:selectOneMenu>

Liste non droulante avec


<h:selectOneListbox>

JSF

JSF - page 112

Listes choix multiple

R. Grin

JSF

page 113

Botes cocher avec


<h:selectManyCheckbox>

Liste droulante avec <h:selectManyMenu>

Liste non droulante avec


<h:selectManyListbox>

R. Grin

JSF

JSF - page 114

19

Cours JSF/Java EE

30/11/2011

Classe SelecItem

Les listes - Exemple


<h:selectOneListbox value="#{bean.choix}">
<f:selectItem itemLabel="choix"
itemValue="#{bean.option}" />
<f:selectItem itemLabel="autre choix"
itemValue="false" />
<f:selectItems value="#{bean.options}"/>

Paquetage javax.faces.model

Donne un label, une valeur et dautres


proprits dune liste de GUI

Utilise pour la valeur (attribut value) des tags


<f:selectItem> et <f:selectItems>

</h:selectOneListbox>

Ce qui est dsign par f:selectItem et f:selectItems sera


affich dans la liste. Le choix fait par lutilisateur parmi toutes ces
valeurs, est rang dans bean.choix (attribut value de
selectOneListBox)
Les entres de la liste qui correspondent lattribut value
R. Grin prslectionnes
JSFdans la liste
JSF - page 115
sont

<f:selecItems>

R. Grin

JSF

page 116

Schma de code pour <f:selecItems>


public static SelectItem[]

Son attribut value peut dsigner un tableau,


une collection ou une map

Le plus souvent, on part dune liste dlments


et on la transforme en tableau ou collection de
SelectItem

JSF

JSF - page 117

Autre faon de faire (JSF 2.0)

SelectItem[] items = new


SelectItem[size];
for (Object x : entities) {
items[i++] =

Le transparent suivant donne un schma de


code pour une telle transformation (souvent
fourni sous la forme dune mthode static
utilitaire)

R. Grin

getSelectItems(List<?> entities) {

}
return items;
}
R. Grin

JSF

JSF - page 118

Chausse-trappes avec les listes

Pour viter la complication de la


transformation en SelectItem, on peut
utiliser les attributs var, itemValue et
itemLabel
Exemple :
<f:selectItems
value="#{ecoleController.personnes}"
var="personne"
itemValue="#{personne.id}"
itemLabel="#{personne.nom}"/>

La variable personne contient


un lment de la liste dsigne par
R. Grin
JSF
value

new SelectItem(x, x.toString());

page 119

Quelques chausse-trappes que lon peut


rencontrer avec les listes droulantes sont
exposes dans les transparents suivants

En particulier avec les convertisseurs et les


validateurs

R. Grin

JSF

page 120

20

Cours JSF/Java EE

30/11/2011

Conversion pour les listes droulantes

Comment se fait la conversion entre les


lments dune liste et ce qui est affich ?

Par exemple, une liste dcoles et ce qui est


affich ?

Il faut bien comprendre que le composant JSF


va tre transform en lment(s) HTML et que
toutes les valeurs vont tre transformes en
String ; en retour, une valeur choisie par
lutilisateur sera une String quil faudra
ventuellement convertir en un autre type

R. Grin

JSF

page 121

Dsigner un convertisseur

Entre fictive de la liste

Si la liste contient des pays, de type Pays, il faut


un convertisseur pour passer du type Pays
String (pour le passage en HTML) et vis-versa
(pour le rangement du choix sous la forme dune
instance du type Pays)

On aura un message derreur si on veut mettre


une 1re entre du type Choisissez un pays
car cette premire entre nest pas du type
Pays, mme avec lattribut noSelectionOption
true (voir transparent suivant), si on ne traite pas
ce cas particulier dans le convertisseur

R. Grin

page 122

Convertisseurs standards

<h:selectOneMenu
value="#{myBean.selectedItem}">
<f:selectItems
value="#{myBean.selectItems}" />

Fournis avec JSF

Exemple :
<inputText
value="#{employe.dateNaissance}">
<f:convertDateTime
pattern="dd/MM/yyyy"/>
</inputText>

<f:converter converterId="fooConverter"/>
</h:selectOneMenu>

JSF

fooConverter dsigne un convertisseur qui

convertit des String dans le type de


myBean.selectedItem et vis-versa
R. Grin

JSF

page 123

crire un convertisseur

Validation dun choix dans une liste

Classe Java qui implmente linterface


Converter (paquetage javax.faces.convert)
qui contient 2 mthodes
Object getAsObject(FacesContext,
UIComponent, String)
qui transforme une chane de caractres en
objet
String getAsString(FacesContext,
UIComponent, Object)
qui transforme un objet en chane de
caractres

R. Grin

JSF

page 125

JSF vrifie que le choix qui est envoy au


serveur est bien un des choix proposs
lutilisateur

a implique que les choix proposs soient


connus par JSF au moment de la validation

Si les choix dpendent dune proprit dun


backing bean (par exemple, un pays pour une
liste de villes dun certain pays), il faut donner
la bonne porte au bean pour que les choix
puissent tre calculs correctement au
moment de la validation (View ou Session par
exemple)

21

Cours JSF/Java EE

30/11/2011

Bean basique et bean gr

Rappel : un bean cest une classe java qui suit


certaines conventions

Annexe sur Java beans

Constructeur vide,
Pas dattributs publics, les attributs doivent avoir
des getter et setters, on les appelle des proprits.

Une proprit nest pas forcment un attribut

Si une classe possde une mthode getTitle() qui


renvoie une String alors, on dit que la classe
possde une proprit title ,
Si book est une instance de cette classe, alors dans
une page JSF #{book.title} correspondra un appel
getTitle() sur lobjet book

Bean basique et bean gr

Une proprit boolenne peut tre dfinie par


la mthode isValid(), au lieu de getValid()

Ce sont bien les mthodes qui dfinissent une


proprit , pas un attribut. On peut avoir
isValid() sans variable valid .

Bean basique et bean gr

Bean basique et bean gr

Rgle pour transformer une mthode en


proprit

Commencer par get, continuer par un nom


capitalis, ex getFirstName(),
Le nom de la proprit sera firstName
On y accdera dans une page JSF par
#{customer.firstName} o customer est linstance du
bean et firstName le nom de la proprit,
Cela revient appeler la mthode getFirstName()
sur lobjet customer.

Exemples de proprits
Nom de mthode

: proprits boolennes
getValid() ou isValid() (recommand),
Nom de la proprit : valid
Accs par #{login.valid}
Exception 2 : proprits majuscules
Si deux majuscules suivent le get ou le
set, la proprit est toute en majuscule,
Ex : getURL(),
Proprit : URL,
Accs par #{website.URL}

Nom de proprit

Utilisation dans une page JSF

Exception 1

getFirstName
setFirstName

firstName

isValid
setValid
(boolen)

valid

getValid
setValid
(boolen)

valid

getZIP
setZIP

ZIP

#{customer.firstName}
<h:inputText
value="#{customer.firstName}"/>
#{login.valid}
<h:selectBooleanCheckbox
value="#{customer.valid}"/>
#{login.valid}
<h:selectBooleanCheckbox
value="#{customer.valid}"/>
#{address.ZIP}
<h:inputText value="#{address.ZIP}"/>

22

Cours JSF/Java EE

30/11/2011

Accder aux objets Request et Response

Annexe pour le codage des backing beans

Pas daccs automatique !

Il faut penser diffremment, il faut


considrer les formulaires comme des objets.

Si vous avez quand mme besoin daccder


la requte et la rponse, le code est un peu
complexe

Utile pour : manipuler la session, par exemple rgler


la dure.
Manipulation des cookies explicite, consulter le
user-agent, regarder le host, etc.

Exemple
FacesContext facesContext =
FacesContext.getCurrentInstance();
ExternalContext extContext =
facesContext.getExternal();
HttpServletRequest response =
(HttpServletRequest)extContext.getResponse();
response.sendRedirect(url);

Faire afficher un message derreur


String msg = "Compte source n'existe pas";
FacesMessage facesMsg =
new FacesMessage(
FacesMessage.SEVERITY_ERROR,
msgResume, msgDetails);
FacesContext.getCurrentInstance()
.addMessage("transfert:source",
facesMsg);

23

Vous aimerez peut-être aussi