JSF : Java Server Faces Jean-Jacques LE COZ Plan Introduction ◆ Technologie ◆ Introduction JSF introduction ■ Un standard Java EE (Java Community Process) ■ ■ Java Specification Request : JSR-127 Une architecture basée sur des composants Framework identique à Swing et AWT ■ Ensemble de composants standards ■ ■ ■ UI Components Extensible ■ Possibilité de créer de nouveaux composants UI Les technologies Java Web JSF : pourquoi faire ? ■ ■ Construction d'interfaces Web Avantages Séparation entre présentation et comportement ■ Contrôle au niveau composant ■ Composant UI avec état statefull ■ Événement facilement couplé au code côté serveur ■ Associe les concepts connus d'événementiel et d'application Web N tiers ■ Technologie côté serveur Serveur Web accès page requête HTTP mapage.jsp Navigateur réponse HTTP rendu HTML monUI JSF et MVC 2 ■ Respecte le modèle MVC 2 ■ ■ Mapping HTML/Objet Plus simple que ses concurrents Spring MVC ■ Struts ■ ■ Plus riche Listeners ■ Validators ■ Converters ■ Technologie JSF technologie ■ Création dynamique d'interfaces graphiques ■ ■ ■ Notion de Renderer (support de différents clients) Côté serveur La technologie combine Pages JSP ■ Composants graphiques événementiels ■ Observateurs d'événements (Contrôleurs) ■ Classes javaBean ■ Filtres de saisies (validité, changement de type) ■ JSF : protocole événementiel Événement FacesServlet (contrôleur) Page JSP Composants UI Réponse (vues) Observateur d'événements JavaBeans (modèle) Cycle de vie ■ Lorsque la page est exécutée ■ Un arbre d'objets Java est créé ■ Les objets de cet arbre ■ ■ ■ Transformation de l'arbre ■ Flux de rendu propre à la technologie du client ■ ■ Courants : UIComponent Racine : UIViewRoot HTML, XHTML, WML, XML, … A chaque soumission de vue ■ Reconstitution de l'arbre de composants API JSF permet d'accéder à l'arbre JSF : modèle MVC 2 (1) ■ Modèle ■ ■ Vue ■ ■ Composants JavaBean, POJO Pages JSP avec composants UI Contrôleur ■ Servlet : Faces Servlet JSF : modèle MVC 2 (2) ■ Actions Listeners (observateur d'événements) ■ Classes d'action (ManagedBean) ■ ■ Filtres Validators ■ Converters ■ JSF : configuration ■ Fichiers ■ web.xml ■ Déclaration du contrôleur principal ■ ■ Faces Servlet faces-config.xml ■ Déclaration des règles de navigation ■ ■ ■ ■ Statiques ou dynamiques Déclaration des javaBeans gérés Déclaration des validators construits Déclaration des converters construits Composants UI ■ Intégrés dans les pages JSP ■ ■ Standards ■ ■ Par des custom tags spécifiques Ils représentent tous les objets HTML Construits Il est possible de développer ses propres UI ■ Offerts par des éditeurs ■ ■ ADF Oracle, MyFaces, ICEfaces, JBoss, ... Libraires UI ■ Déclarées dans chaque page JSP <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> < %@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> ■ UI déclarés dans une section <f:view> <f:view> <h:form id="calcForm"> ... </h:form> </f:view> Les UI ■ Les UI statiques (objets HTML) Ils sont déclarés après le tag <h: ...> ■ Ils peuvent posséder une identité ■ ■ ■ Attribut id=''identifiant'' Les UI dynamiques (contrôle, validation, convertion, ...) ■ Ils sont déclarés après le tag <f: ...> UI Composants ■ Libellés ■ ■ Zones de saisie ■ ■ <h:inputText>, <h:inputHidden>, <h:inputSecret> Zones d'affichage ■ ■ <h:outputLabel> <h:outputText> Messages ■ <h:message> UI Messages ■ Message pour un UI <h:message> ■ Attribut for=''Id du composant'' ■ ■ Messages pour plusieurs UI ■ ■ <h:messages> Attributs de présentation ■ Style CSS UI Composites ■ Panneaux de type tableau ■ ■ <h:panelGrid columns=''3''> Panneaux ensemble de composants ■ <h:panelGroup> UI de sélection (1) ■ Listes de sélection <h:selectOneListbox> ■ <h:selectManyListbox> ■ ■ Menus de sélection <h:selectOneMenu> ■ <h:selectManyMenu> ■ UI de sélection (2) ■ Radio bouton ■ ■ <h:selectOneRadio> Boites à cocher <h:selectBooleanCheckbox> ■ <h:selectManyChekbox> ■ UI Tableau de données ■ Déclaration ■ ■ Grand nombre d'attributs ■ ■ <h:dataTable> Richesse de présentation Attributs de comportement ■ Richesse fonctionnelle Exemple de dataTable <h:dataTable border="1" value="#{unManagedBean.listeDePersonnes}" var="item" > <h:column> <f:facet name="header" > <h:outputText value="Nom"/> </f:facet> <h:outputText value="#{item.nom}"/> </h:column> <h:column> <f:facet name="header" > <h:outputText value="Prénom"/> </f:facet> <h:outputText value="#{item.prenom}"/> </h:column> </h:dataTable> dataTable imbriquée <h:dataTable border="1" value="#{unManagedBean.listeDePersonnes}" var="item" > <h:column> <f:facet name="header" > <h:outputText value="Nom"/> </f:facet> <h:outputText value="#{item.nom}"/> </h:column> <h:column> <f:facet name="header" > <h:outputText value="Prénom"/> </f:facet> <h:outputText value="#{item.prenom}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="téléphones"/> </f:facet> <h:dataTable value="#{item.listeDeTelephones}" var="tel" > <h:column> <h:outputText value="#{tel.numero}"/> </h:column> </h:dataTable> </h:column> </h:dataTable> UI Lien (1) ■ Déclaration du lien ■ ■ Libellé du lien ■ ■ <f:verbatim>libellé</f:verbatim> Action ■ ■ <h:commandLink> Attribut action=''#{bean.methode}'' Listener Attribut actionListener=''#{listener.methode}'' ■ Méthode void methode(ActionEvent) ■ UI Lien (2) ■ Lien sur une image ■ ■ <h:graphicImage> Exemple ■ <h:graphicImage value=''/image.png'' /> UI Bouton ■ Déclaration du bouton ■ ■ Libellé du bouton ■ ■ Attribut value=''libellé'' Action ■ ■ <h:commandButton> Attribut action=''#{bean.methode}'' Listener Attribut actionListener=''#{listener.methode}'' ■ Méthode void methode(ActionEvent) ■ JSF exemple Bonjour Le Monde <%@ page contentType="text/html" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="core" %> <core:view> <html:outputText value="Bonjour le Monde ! (en JSF !)" /> </core:view> Anatomie de la page <%@ page contentType="text/html" %> Type de contenu : HTML <%@ taglib uri="http://java.sun.com/jsf/html" prefix="html" %> Import des taglibs de <%@ taglib uri="http://java.sun.com/jsf/core" prefix="core" %> base de JSF (requis) <core:view> Définit une vue JSF (requis) <html:outputText value="Bonjour le Monde ! (en JSF !)" /> Tag outputText Intégration avec JSP JSP avec composants UI (1) ■ Pour utiliser les «custom tag» JSF <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> JSP avec composants UI (2) ■ Section JSF au sein de la page JSP <body bgcolor="#FFFFFF"> <f:view> VUE JSF </f:view> ... </body> ... JSP avec composants UI (3) ■ Formulaire JSF <h:form id="loginForm"> .... </h:form> JSP avec composants UI (4) ■ Composant de type TextField JSF <h:inputText id="userid" size="15" required="true" value="#{LoginServer.userid}" > JSP avec composants UI (5) ■ TextField JSF avec validation <h:inputText id="userid" size="15" required="true" value="#{LoginServer.userid}" > <f:validate_length minimum="4" maximum="7" /> </h:input_text> <h:messages id="errors1" for="userid"/> JSP avec composants UI (6) ■ Bouton JSF <h:command_button id="submit" action="#{LoginServer.loginAction}" value="#{jsfloginBundle.loginSubmitLabel}"> </h:command_button> Référence à des ressources ■ Permet l'internationalisation <f:loadBundle basename="jsflogin.Resources" var="jsfloginBundle"/> Navigation ■ JSF implémente un automate à états finis A l'aide de règles de navigation ■ Avec une clef de navigation (outcome) ■ ■ Statique ■ ■ En dur dans la page JSP Dynamique ■ Calculée par un EL JSF (Expression Language) Navigation ■ Décrite dans faces-config.xml ■ Au sein de sections <navigation-rule> ■ ■ <from-view-id> // page de départ Conditions dans <navigation-case> ■ ■ ■ <from-action-ref> // méthode de classe action <from-outcome> // valeur de sortie de l'action <to-view-id> // page d'arrivée Navigation statique <%@ page contentType="text/html" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="core" %> <core:view> <html:form> <html:commandLink action="coucou" value="Bonjour le Monde"/> </html:form> </core:view> Définition statique ... <navigation-rule> <!-- Indique pour quelle vue courante la règle s'applique → <from-view-id>/index.jsp</from-view-id> <navigation-case> <!-- Si l'outcome renvoyé est coucou alors JSF passe à la page /bonjour.jsp --> <from-outcome>coucou</from-outcome> <to-view-id>/bonjour.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config> Navigation dynamique ... <navigation-rule> <from-view-id>/login.jsp</from-view-id> <navigation-case> <description>cas d'un login avec succes</description> <from-action>#{LoginServer.loginAction}</from-action> <from-outcome>success</from-outcome> <to-view-id>/success.jsp</to-view-id> </navigation-case> ... </faces-config> Exemple de classe Action public class LoginServer extends Object { ... public String loginAction() { if ( userid.equals("scott") && password.equals("tiger") ) { System.out.println("returning success"); return "success"; } else { System.out.println("returning failure"); return "failure"; } ... Les classes Listener ■ Invocation Action Listener=''#{actionlistener} ■ La classe doit implémenter L'interface ActionListener La méthode public void processAction(ActionEvent event) Possibilités Accès à l'état des composants UI Accès aux objets associés au composant qui a déclenché l'événement public class FormePersonneListener implements ActionListener { public void processAction(ActionEvent event) throws AbortProcessingException { FacesContext context = FacesContext.getCurrentInstance(); UIComponent component = event.getComponent(); if (component.getId().equals("submit")) { Application application = FacesContext.getCurrentInstance().getApplication(); PersonneBean bean = (PersonneBean) application.getVariableResolver().resolveVariable(context,"leBean"); bean.setStatut(true); } } Accès aux attributs ■ JSF accède aux getter/setter par réflexion Appel aux méthodes get Sur les composants de sortie d'information Exemple : <h:outputText Appel aux méthode set Sur les composants d'entrée d'information Exemple : <h:inputText Système de nommage #{ManagedBean.attribut} #{ManagedBean.attribut.attribut} Déclaration des Java Bean ■ Dans le fichier faces-config.xml ... <managed-bean> <managed-bean-name>LoginServer</managed-bean-name> <managed-bean-class>jsflogin.loginServer</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config> Exemple de modèle Exemple de faces-config <managed-bean> <managed-bean-name>AdresseBean</managed-bean-name> <managed-bean-class>modele.Adresse</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>EtudiantBean</managed-bean-name> <managed-bean-class>modele.Etudiant</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>adresse</property-name> <property-class>modele.Adresse</property-class> <value>#{AdresseBean}</value> </managed-bean> Exemple de page <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> <title>Etudiant</title> </head> <%@ page contentType="application/xhtml+xml" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <body bgcolor="white"> <f:view> <h:form id="etudiantForm" > <h:inputText value="#{EtudiantBean.nom}"/> <h:inputText value="#{EtudiantBean.adresse.ville}"/> <h:commandButton id="submit" action="succes" value="Valider"/> </h:form> </f:view> </body> </html> Liaison Java – Composant UI Principe du binding Permet de lier un composant JSF avec un attribut d'un bean Lorsque le binding est déclaré alors il est possible d'agir sur le composant Beaucoup de composant supporte l'attribut binding Exemple • <html:dataTable binding="#{bank.dataTable}" • Le bean bank doit posséder une référence sur le composant DataTable Exemple public class Bank { … private UIData dataTable; … Manipulation de dataTable; Fichiers de configuration Fichiers de déploiement ■ Le fichier faces-config.xml – – – ■ Le fichier web.xml – ■ Déclaration des ManagedBean Déclaration des règles de navigation Déclaration des classes de validation Déclaration de la Faces Servlet Dans le répertoire WEB-INF/ Déclaration de Servlet Faces ■ Dans le fichier web.xml <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup> 1 </load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> Déclaration de faces-config.xml ■ Dans le fichier web.xml <context-param> <param-name>javax.faces.application.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> Stockage de l'état de la page ■ Dans le fichier web.xml <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> Valeurs possibles : client (champ caché dans la page) ou server Conclusion Conclusion ■ ■ ■ ■ ■ ■ Framework standardisé Respecte le MVC2 Logique de programmation événementielle Extensible Meilleure intégration des JavaBeans Bientôt des GUI Builder JSF Vendeurs ■ Implémentation de référence ■ ■ SUN MICROSYSTEM Communautés libres et Open Source MyFaces [Consortium Apache] ■ ICEFaces [ICEfaces.org] ■ ■ Extensions Librairie ADF Faces Components [Oracle] ■ Librairie RichFaces [JBoss ] ■ Bibliographie ● ● ● ● Livres Java Server Faces ■ Éditeur: Prentice Hall ■ Auteurs: David M. Geary, Cay S. Horstmann Java Server Faces Programming ■ Éditeur: Mc Graw Hill ■ Auteurs: Budi Kurniawan Sites Web ■ http://java.sun.com/j2ee/javaserverfaces ■ http://www.jsfcentral.com/