Une page ''JSF'' avec l'utilisation des ''EL'' utilise du code ''HTML'' dans lequel est mis des tags définis par les spécifications des ''JSF''. Ce sont ces tags qui appellent les fonctions ''Java''. Le code généré par les appels aux fonctions ''JSF'' est du ''XHTML 1.0''. Avec ''JSF'', les ''EL'' s'utilisent avec le symbole ''#''. Tous les exemples ci-dessous utilisent le [[helloworld:design_pattern:bean:java|BeanPersonne]]. =====Cycle de vie===== {{:helloworld:web:java:jsf:cycle.png|Cycle de vie}} [[http://bet-nafet.ma/expert/Java/Tutoriels/J2EE/JSFAvancees.html|JavaServer Faces - techniques avancées]] {{ :helloworld:web:java:jsf:javaserver_faces_2020-04-26_7_23_41_pm_.html |Archive le 2015}} {{:helloworld:web:java:jsf:jeett_dt_016.png|Cycle de vie}} [[http://docs.oracle.com/javaee/7/tutorial/jsf-intro006.htm#BNAQQ|The Lifecycle of a JavaServer Faces Application]], {{ lang:java:jeett.pdf |The Java EE Tutorial}} =====Création du projet===== Nécessite un projet de type [[ide:eclipse:projet|Dynamic Web Project]]. =====Exemple 1 - La base===== Insert title here


Rendu 15 est un nombre impair. 16 est un nombre pair. =====Exemple 2 - Utilisation d'un Bean===== Dans le cas de Beans utilisés par JSF, la valeur par défaut définie lors de la définition de l'attribut ou par le constructeur est initialisé à 0 (pourquoi ????). Il est donc nécessaire de définir une fonction ''init'' avec l'annotation ''@PostConstruct''. L'exemple est présenté ici afin de garder une cohérence avec les autres pages ([[helloworld:web:java:servlet|servlet]], [[jsp|JSP]] et [[jsp_jstl_el|JSP+JSTL]]). Cependant, il n'est pas possible de définir dans ''JSF'' la valeur d'attribut sans intervention de l'utilisateur. Il est indispensable que le nom de la classe définissant le Bean managé commence par une majuscule. En effet, lorsqu'on désignera la classe, il faudra taper ''com.llgc.BeanPersonne'' mais si l'on soit désigner la référence à un attribut, il faudra taper ''beanPersonne.taille'' avec une minuscule. Insert title here

La personne possède une taille de #{beanPersonne.taille} cm et n'a pas les yeux bleus.

Code à ajouter au BeanPersonne : @PostConstruct public void init () { setTaille (150); setYeuxBleus (true); setDiplomes (null); } Rendu : La personne possède une taille de 150 cm et a les yeux bleus. =====Exemple 3 - Formulaire avec Bean global et session===== Insert title here

La valeur retour de la méthode ''action'' définie la page de redirection. package com.llgc; import javax.faces.bean.ManagedBean; @ManagedBean public class Index3Action { public String action () { return "Servlet3"; } } Rendu du formulaire : {{:helloworld:web:java:servlet:rendu_ex3-1.png|Rendu du formulaire}} Rendu de la réponse : {{:helloworld:web:java:servlet:rendu_ex3-2.png|Rendu de la réponse}} =====Exemple 3b - avec validation des données===== Dans le cas de ''JSF'', l'utilisation de ''Javascript'' n'est plus obligatoire mais reste conseillé pour réduire la charge serveur. L'utilisation de ''Javascript'' n'empêche pas la vérification coté serveur, une page est facilement traficable depuis les navigateurs. package com.llgc; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.FacesValidator; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; @FacesValidator("com.llgc.BeanPersonneValidatorTaille") public class BeanPersonneValidatorTaille implements Validator { @Override public void validate (FacesContext arg0, UIComponent arg1, Object arg2) throws ValidatorException { int taille; try { taille = Integer.parseInt (arg2.toString ()); } catch (NumberFormatException e) { FacesMessage msg = new FacesMessage ("Échec lorg de la vérification de la taille.", arg2.toString () + " n'est pas un nombre."); msg.setSeverity (FacesMessage.SEVERITY_ERROR); throw new ValidatorException (msg); } if (taille < 30 || taille > 250) { FacesMessage msg = new FacesMessage ("Échec lorg de la vérification de la taille.", "La taille doit être comprise entre 30 et 250 cm."); msg.setSeverity (FacesMessage.SEVERITY_ERROR); throw new ValidatorException (msg); } } } Insert title here La balise ''h:message'' permet d'indiquer la position et éventuellement le style du message d'erreur. Si cette balise est absente, le message sera affiché à la position par défaut. Rendu, échec de conversion en nombre : {{:helloworld:web:java:jsf:rendu_3b_1.png|Rendu exo3, échec string en nombre}} C'est bien le message ''Enter Only Digits'' qui est affiché et pas ''auie n'est pas un nombre.''. Je pense que comme la propriété ''taille'' est un nombre, il doit y avoir une conversion implicite avant la soumission au Bean validateur. Rendu, échec du domaine du nombre : {{:helloworld:web:java:jsf:rendu_3b_2.png|Rendu exo3, échec domaine du nombre}} Rendu, succès : {{:helloworld:web:java:jsf:rendu_3b_3.png|Rendu exo3, succès}} ====Validateurs implémentés par défaut==== '''' '''' '''' '''' : nécessite que la chaîne de caractère doit être non-vide. '''' =====Exemple 3c - avec convertisseur des données===== package com.llgc; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; import javax.faces.convert.FacesConverter; @FacesConverter("com.llgc.BeanPersonneConvertisseurYeuxBleus") public class BeanPersonneConvertisseurYeuxBleus implements Converter { @Override public Object getAsObject (FacesContext arg0, UIComponent arg1, String arg2) { if (arg2.equals ("non")) { return new Boolean (false); } if (arg2.equals ("oui")) { return new Boolean (false); } throw new ConverterException (new FacesMessage ("Échec de la convertion en boolean", arg2 + " ne vaut ni oui, ni non.")); } @Override public String getAsString (FacesContext arg0, UIComponent arg1, Object arg2) { if (arg2 instanceof Boolean) { if ((Boolean)arg2) { return "non"; } else { return "oui"; } } throw new ConverterException (new FacesMessage ("Échec de la convertion en boolean", arg2.toString () + " ne vaut ni oui, ni non.")); } } Insert title here Rendu avec succès : {{:helloworld:web:java:jsf:rendu_3c_1.png|}} Rendu sans succès : {{:helloworld:web:java:jsf:rendu_3c_2.png|}} ====Convertisseurs implémentés par défaut==== '''' '''' '''' =====Exemple 4 - context-param et init-param===== Ajout de trois ''context-param''. EL Faces Servlet javax.faces.webapp.FacesServlet user utilisateur password mot de passe driver com.mysql.jdbc.Driver Faces Servlet /faces/* Insert title here

nom : ${initParam['user']}
pass : ${initParam['password']}
driver : ${initParam['driver']}

Les ''init-param'' ne sont plus du tout accessibles en ''JSF'', ce qui démontre bien la volonté de séparer la représentation visuelle (''.xhtml'') des ''servlets''. Rendu : nom : utilisateur pass : mot de passe driver : com.mysql.jdbc.Driver =====Exemple 5 - Cookies===== Il n'est pas possible de modifier les cookies sans passer par des commandes Java. Il est donc nécessaire de passer par l'intermédiaire d'une ''servlet''. EL Faces Servlet javax.faces.webapp.FacesServlet Faces Servlet /faces/* Il est important de noter la présence de ''/faces'' au début de l'URL de redirection ''/faces/indexjsf5.xhtml''. Le fichier se trouve bien dans le dossier ''WebContent'' et non pas dans un hypothétique dossier ''WebContent/faces''. Sans cette dénomination (conformément au fichier ''web.xml''), les tags ''JSF'' ne seraient pas interprétés. Par contre, je n'ai pas réussi mettre le fichier ''indexjsf5.xhtml'' dans le dossier ''WEB-INF'' et y accéder via ''/faces/WEB-INF/indexjsf5.xhtml''. La solution peut être de remplacer dans ''web.xml'', ''/faces/*'' par ''*.xhtml'' et d'utiliser le lien de redirection ''/WEB-INF/indexjsf5.xhtml''. package com.llgc; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class ServletJSF5 */ @WebServlet ("/ServletJSF5") public class ServletJSF5 extends HttpServlet { /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding ("UTF-8"); String value = getCookie (request.getCookies (), "compteur"); response.setContentType ("text/html"); int compteur = 0; if (value != null) { compteur = Integer.parseInt (value); } compteur++; Cookie c = new Cookie ("compteur", "" + compteur); c.setMaxAge (3600); response.addCookie (c); this.getServletContext ().getRequestDispatcher ("/faces/indexjsf5.xhtml").forward (request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet (request, response); } // Renvoie la valeur d'un cookie. protected static String getCookie (Cookie[] cookies, String cookieName) { if (cookies == null) { return null; } for (int i = 0; i < cookies.length; i++) { if (cookieName.equalsIgnoreCase (cookies[i].getName ())) { return cookies[i].getValue (); } } return null; } } Insert title here

Rendu 1 : Pas de cookie, allez cuisiner !!! Rendu 2 : compteur : 1 =====Exemple 6 - Affichage d'une liste dans un tableau===== La liste est générée par une classe Java [[helloworld:web:java:servlet#exemple_6_-_affichage_d_une_liste_dans_un_tableau|Liste6]] et affiche un type [[helloworld:design_pattern:bean:java#cas_general|BeanPersonne]]. Insert title here
Taille Yeux bleus
${perso.taille} ${perso.yeuxBleus}
Rendu : {{:helloworld:web:java:servlet:rendu_ex6.png|Rendu exemple 6}} Insert title here Taille #{perso.taille} Yeux bleus #{perso.yeuxBleus} Le fichier ''.css'' ([[http://www.mkyong.com/jsf2/jsf-2-0-jdbc-integration-example/|JSF 2.0 + JDBC integration example]] {{ :helloworld:web:java:jsf:jsf_2.0_jdbc_integration_example_mkyong.com_2020-04-26_7_39_17_pm_.html |Archive du 29/08/2012 le 26/04/2020}}) doit être placé dans le dossier ''WebContent\resources\css''. .order-table{ border-collapse:collapse; } .order-table-header{ text-align:center; background:none repeat scroll 0 0 #E5E5E5; border-bottom:1px solid #BBBBBB; padding:16px; } .order-table-odd-row{ text-align:center; background:none repeat scroll 0 0 #FFFFFFF; border-top:1px solid #BBBBBB; } .order-table-even-row{ text-align:center; background:none repeat scroll 0 0 #F9F9F9; border-top:1px solid #BBBBBB; } Rendu : {{:helloworld:web:java:jsf:rendu_ex6-2.png|Rendu exemple 6}} =====Exemple 7 - HTML5===== La génération de page au format HTML5 nécessite l'utilisation des JSF 2.2 avec JavaEE 7 et Tomcat 8. [[https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HTML5-JSF/html5jsf.html|Creating HTML5 Pages in JavaServer Faces 2.2]] {{ :helloworld:web:java:jsf:java_ee7_creating_html5_pages_using_jsf_2.2_2020-04-26_7_41_06_pm_.html |Archive le 26/04/2020}}. Faire les modifications suivantes : ^Remplacer^par^ |''''|''%%%%''| |''''|''''| |''''|''''| |''%%%%''|''%%%%''| |''%%%%''|''%%%%''| |''%%%%''|''%%%%''| |''%%
%%''|''%%%%''|