Projets
Pages enfant
  • 1.9.1 Généralités

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.
Balise Wiki
{note}
Bon pour relecture
{note}
{toc}

h1. Introduction

Ce chapitre n'a pas la prétention d'être une formation à JSF. Pour plus d'informations vous pouvez vous reporter à une documentation comme [
Remarque

Bon pour relecture

Sommaire

Introduction

...

http://www.jmdoudoux.fr/java/dej/chap-jsf.htm

...

Avec ESUP-Commons V2 nous utilisons facelet (Cf. Facelet1.7.2 Facelet). Les pages sont suffixées en .xhtml. Elle sont écrites en XML ce qui permet d'utiliser des espaces de noms et des commentaires XML.

JSF 1.2 ou JSF 2.0 ?

ESUP-Commons V2 permet d'utiliser JSF 1.2 ou JSF 2.0 !

JSF 2.0 apporte de nombreuse améliorations par rapport à JSF 1.2. De plus, en JSF 2.0 il sera, a priori, beaucoup plus facile de faire cohabiter différentes librairies de composants. Les dernières librairies (notamment celles qui offrent des composants de hauts niveau et permettent un fonctionnement en Ajax) évoluent beaucoup plus en JSF 2.0 qu'en JSF 1.2.

Malheureusement, JSF 2.0 n'est pas compatible avec le mode portlet ! Pour utiliser JSF 2.0 en mode portlet il faut utiliser un portlet bridge non normalisé et ce dernier ne fonctionne qu'en mode portlet 2.0 alors que uPortal 3.2 ne supporte que le mode portlet 1.0 (uPortal 3.3 devant supporter le mode portlet 2.0). De plus, certaines librairies sont encore en version beta pour JSF 2.0 (ex de Trinidad à l'heure à laquelle nous écrivons cette page).

C'est la raison pour laquelle ESUP-Commons V2 propose d'utiliser JSF 1.2 ou JSF 2.0 suivant le contexte cible :

  • JSF 1.2 pour le développement d'une portlet
  • JSF 2.0 pour le développement d'une servlet (typiquement une application importante contenant beaucoup d'écrans et pour laquelle on souhaite avoir un bon niveau de productivité lors de l'écriture des pages)

Exemple de page

Bloc de code
]. Ne sont abordés ici que quelques éléments.

Avec ESUP-Commons V2 nous utilisons facelet (Cf. [Facelet|PROJCOMMONS:1.7.2 Facelet][PROJCOMMONS:1.7.2 Facelet]). Les pages sont suffixées en .xhtml. Elle sont écrites en XML ce qui permet d'utiliser des espaces de noms et des commentaires XML.

h2. JSF 1.2 ou JSF 2.0 ?

ESUP-Commons V2 permet d'utiliser JSF 1.2 ou JSF 2.0 \!


JSF 2.0 apporte de nombreuse améliorations par rapport à JSF 1.2. De plus, en JSF 2.0 il sera, a priori, beaucoup plus facile de faire cohabiter différentes librairies de composants. Les dernières librairies (notamment celles qui offrent des composants de hauts niveau et permettent un fonctionnement en Ajax) évoluent beaucoup plus en JSF 2.0 qu'en JSF 1.2.


Malheureusement, JSF 2.0 n'est pas compatible avec le mode portlet \! Pour utiliser JSF 2.0 en mode portlet il faut utiliser un portlet bridge non normalisé et ce dernier ne fonctionne qu'en mode portlet 2.0 alors que uPortal 3.2 ne supporte que le mode portlet 1.0 (uPortal 3.3 devant supporter le mode portlet 2.0). De plus, certaines librairies sont encore en version beta pour JSF 2.0 (ex de Trinidad à l'heure à laquelle nous écrivons cette page).

C'est la raison pour laquelle ESUP-Commons V2 propose d'utiliser JSF 1.2 ou JSF 2.0 suivant le contexte cible :
* JSF 1.2 pour le développement d'une portlet
* JSF 2.0 pour le développement d'une servlet (typiquement une application importante contenant beaucoup d'écrans et pour laquelle on souhaite avoir un bon niveau de productivité lors de l'écriture des pages)

h1. Exemple de page

{code}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns    xmlns:f="http://java.sun.com/jsf/core"
	xmlns    xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns    xmlns:t="http://myfaces.apache.org/tomahawk"
	xmlns    xmlns:h="http://java.sun.com/jsf/html"
	xmlns    xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view locale="#{sessionController.locale}">
	<t:htmlTag value="head">
	<    <head>
        <!-- Commentaire -->
		<title><h        <title><h:outputText value="#{applicationService.name}" /></title>
		<ui        <ui:repeat value="#{tagsConfigurator.stylesheets}" var="path">
			<t            <t:stylesheet path="#{path}" />
		<        </ui:repeat>
		<ui        <ui:repeat value="#{tagsConfigurator.scripts}" var="path">
			<script type=            <script type="text/javascript" src="#{path}" />
		<        </ui:repeat>
	</t:htmlTag>
	<t:htmlTag value="body" styleClass="fl-theme-app">
		<ui    </head>
    <body>
        <ui:include src="_include/_header.xhtml" />
		<t:div        <div id="welcomepages">
			<t:div            <div id="navigationHeader" styleClass="app-pagebar">
				<h>
                <h:form id="nav_header" styleClass="app-form" />
			</t:div>
			<t:div styleClass="app-body">
				<t:div styleClass="app-navigation">
				</t:div>
				<t:div styleClass="app-content">
					<t:htmlTag value="br" />
					<ui            </div>
            <div>
                <div>
                </div>
                <div>
                    <t:htmlTag value="br" />
                    <ui:insert name="allContent" />
				</t:div>
				<t:div                </div>
                <div style="clear:both;" />
			</t:div>
			<t:div            </div>
            <div id="navigationFooter"
				styleClass                class="fl-container-flex app-pagebar">
				<h:form                 <h:form id="nav_footer" styleClass="app-form" />
			</t:div>
		</t:div>
		<t:div styleClass="app-footer">
			<h            </div>
        </div>
        <div>
            <h:outputText value="#{applicationService.name} " />
			<h            <h:outputText value="v#{applicationService.version} - " />
			<h            <h:outputText value="#{applicationService.copyright}" />
		</t:div>
	</t:htmlTag>        </div>
    </body>
</f:view>

</html>
{code}
Dans la page ci-dessus :

...


* la balise *<html>* est l'élément racine de la page. Il contient aussi la définition des espaces de noms qui permettent de définir les composants JSF que l'on va utiliser. Ici :

...


** *xmlns:f="http:**//java.sun.com/jsf/core"* et *xmlns:h=**"http:**//java.sun.com/jsf/html"* sont les 2 librairies de base de JSF

...


** *xmlns:ui=**"http:**//java.sun.com/jsf/facelets"* est la librairie facelet (NB : En JSF 2.0 facelet est aussi une librairie de base de JSF alors qu'elle est optionnelle en JSF 1.2)

...


** *xmlns:t=**"http:**//myfaces.apache.org/tomahawk"* est une librairie proposée par la fondation Apache qui propose quelques utilitaires (notamment de manipulation du html)

...


** *xmlns\:p=**"http:**//primefaces.prime.com.tr/ui"* est la librairie PrimeFaces qui va apporter des composants de haut niveaux (interface riche et support de Ajax). Elle est donnée ici à titre d'exemple car, suivant les besoins, on utilisera telle ou telle librairie (EichFaces, Trinidad, OpenFaces, etc.)

...

  • la balise JSP <%@include file="_include.jsp"%> permet d'inclure toutes les librairies nécessaires (voir plus loin).
  • La balise JSF <e:page> se charge de la mise en forme globale, que l'on soit en servlet ou en portlet.
  • La balise JSP <%@include file="_navigation.jsp"%> permet d'inclure la barre de navigation, commune à toutes les pages.
  • La balise JSF <e:section> affiche le titre de la page.
  • La balise JSF <h:form> encadre un formulaire.
  • La balise JSF <e:outputLabel> affiche le label d'un formulaire, celui qui possède l'identifiant locale.
  • La balise JSF <e:selectOneMenu> propose un choix simple de valeurs dans une boite déroulante.
  • La balise JSF <f:selectItems> renseigne la balise précédente sur les choix possibles, fournis par la méthode getLocaleItems() du bean preferencesController.
  • La balise JSF <e:commandButton> est un bouton de soumission du formulaire. Lors de la soumission du formulaire, la méthode setLocale() du bean preferencesController est appelée avec la valeur sélectionnée dans la boite déroulante.

Syntaxe EL

JSF dispose d'un Expressions Language (EL) qui lui est propre. Syntaxiquement différent de l'EL de JSP 2.0. Il est utilisable dans les attributs des taglibs JSF. Il permet d'accéder en lecture ou en écriture à des propriétés du contrôleur (dans la mesure où celui-ci implémente des getters/setters sur ses propriétés). Il permet aussi d'invoquer une action du contrôleur (méthode sans paramètres qui renvoie une chaîne).

La syntaxe de base est

Bloc de code

* la balise *<f:view locale=**"#{sessionController.locale}"**>* est la balise JSF servant à inclure les autres balise JSF. La propriété locale permet de définir la langue qui sera utilisée pour les messages.
* la balise *<ui:repeat value="#{tagsConfigurator.stylesheets}" var="path">* permet de répéter n fois un même contenu. n est fonction du nombre d'entrées retournées par la méthode _getStylesheets_ du bean _tagsConfigurator_. Chaque entrée est ensuite positionnée dans une variable (_path_ ici) afin d'être réutilisée dans la boucle.


h1. Syntaxe EL

_JSF_ dispose d'un _Expressions Language_ (_EL_) qui lui est propre. Syntaxiquement différent de l'_EL_ de _JSP_ 2.0. Il est utilisable dans les attributs des _taglibs JSF_. Il permet d'accéder en lecture ou en écriture à des propriétés du contrôleur (dans la mesure où celui-ci implémente des getters/setters sur ses propriétés). Il permet aussi d'invoquer une action du contrôleur (méthode sans paramètres qui renvoie une chaîne).

La syntaxe de base est
{code}
#{beanName.propertyName}

ou

Bloc de code
{code}
ou
{code}
#{beanName.methodName}
{code}
.Il est possible d'accéder à des objets récursivement, par

...

Bloc de code

#{ exemple&nbsp;:
{code}
#{homeController.context.name}
{code}
Il est possible d'accéder à des éléments de tableaux ou de *Map*, par

...

Bloc de code
 exemple&nbsp;:
{code}
#{tableau[1]}
#{hash.key}
#{hash["key"]}
#{hash[keyvar]}
{code}
(dans ce dernier exemple *keyvar* est évalué avant de retrouver l'entrée dans la table *hash*). Certains tableaux associatifs sont définis par

...

 défaut&nbsp;: *param*, *header*, *cookie*, etc.

On peut également utiliser quelques opérateurs logiques (*and*, *or*, *not*, *empty*, ...) ainsi que la plupart des opérateurs mathématiques.

h1.

...

 Navigation entre les pages

...



La navigation entre les pages de l'application est faite en _JSF_ à l'aide de règles de navigation écrites en _XML_, définies dans _esup-commons_ par convention dans le fichier */

...

webapp/

...

WEB-INF/navigation-rules.xml*.

...



Cette approche permet de bien dissocier les contrôleurs de la navigation en elle-même. Quand on appelle une méthode d'un contrôleur, par exemple au moment de la validation d'un formulaire, cette méthode (_callback_) renvoie une simple chaîne de caractères qui sera utilisée par _JSF_ pour trouver la règle de navigation correspondante dans le

...

 fichier *navigation-rules.xml*.

...



Voici ci-dessous un exemple de règle de navigation :

...


{code
}
<navigation-rule>
  <display-name>administrators</display-name>
  <from-view-id>/stylesheets/administrators.jsp</from-view-id>
  <navigation-case>
    <from-outcome>addAdmin</from-outcome>
    <to-view-id>/stylesheets/administratorAdd.jsp</to-view-id>
  </navigation-case>
  <navigation-case>
    <from-outcome>deleteAdmin</from-outcome>
    <to-view-id>
      /stylesheets/administratorDelete.jsp
    </to-view-id>
  </navigation-case>
</navigation-rule>
{code}
La balise *from-view-id* est facultative. Elle donne la vue (page) à partir de laquelle les règles de navigation vont s'appliquer. Si elle n'est pas présente, la règle est potentiellement applicable depuis toutes les pages de l'application.

...



Le noeud *navigation-case* permet de définir une règle de

...

 navigation&nbsp;:
* *from-outcome* est l'action de l'utilisateur. Cette action peut être

...

 définie «&nbsp;en dur&nbsp;» dans la page _JSP_ (par ex. *<h:commandButton value="suivant" action="next"/>*) ou bien être le résultat de l'exécution d'une méthode d'un bean contrôleur de l'application (par ex. *<h:commandButton value="suivant" action="#{controller.value}"/>*).

...


* *to-view-id* donne la page de destination.

...


* *<redirect />* peut être utilisé pour indiquer que l'affichage de la page de destination doit être fait sous forme d'une redirection _HTTP_ (code _HTTP_ 302). Cette balise doit être utilisée pour protéger l'utilisateur des effets de soumission multiple des formulaires à l'aide des boutons « Page précédente » et « Page suivante » des

...

Protection des pages JSP

Les pages JSP ne devraient pas être accessibles directement. En effet, pour accéder aux vues on utilise l'extension .faces pour activer le filtreMyFaces. Une solution pour interdire l'accès aux JSP consiste à définir une contrainte de sécurité dans le /webapps/WEB-INF/web.xml. On utilisera par exemple :

Bloc de code

<security-constraint>
  <display-name>Protect the raw JSP pages</display-name>
  <web-resource-collection>
    <web-resource-name>Raw JSF JSP Pages</web-resource-name>
    <url-pattern>/stylesheets/administrators.jsp</url-pattern>
    <url-pattern>/stylesheets/administratorsAdd.jsp</url-pattern>
    <url-pattern>/stylesheets/administratorsDelete.jsp</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <description>No roles, so no direct access</description>
  </auth-constraint>
</security-constraint>

Bibliothèques utilisées

...

 navigateurs.

h1.

h1.

h1.

<?xml version="1.0" encoding="UTF-8"?>
<\!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
&nbsp;&nbsp; &nbsp;xmlns:f="http://java.sun.com/jsf/core"
&nbsp;&nbsp; &nbsp;xmlns:ui="http://java.sun.com/jsf/facelets"
&nbsp;&nbsp; &nbsp;xmlns:t="http://myfaces.apache.org/tomahawk

...

Afin de ne pas avoir à redéfinir ces bibliothèques dans toutes les pages de votre application, esup-commons est livré avec le fichier _include.jsp à inclure dans l'entête de vos pages JSP, de cette manière :

Bloc de code

<%@include file="_include.jsp"%>

Le contenu de ce fichier est le suivant :

Bloc de code

<%@ page language="java"contentType="text/html; charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>
<%@ taglib uri="http://commons.esup-portail.org" prefix="e"%>

Les tags commençant par <f: et <h: sont donc ceux de MyFaces (l'implémentation JSF de Apache), ceux commençant par <t: sont ceux de Tomahawk (les extensions de MyFaces) et ceux commençant par <e: ceux de esup-commons.

Page d'accueil de l'application

La page d'accueil de votre application se configure différemment suivant que votre application sera utilisée en mode servlet ou en mode portlet.

En mode servlet

En mode servlet, esup-commons propose par défaut une page index.jsp qui fait une redirection vers stylesheets/welcome.faces.

Il est possible de surcharger cette page dans votre application.

En mode portlet

En mode portlet on utilise le paramètre default-view de la portlet org.esupportail.commons.web.portlet.FacesPortlet dont la définition est présente dans le fichier /webapps/WEB-INF/portlet.xml.

Exemple :

Bloc de code

<portlet>
  <portlet-name>esup-formation</portlet-name>
  <portlet-class>
    org.esupportail.commons.web.portlet.FacesPortlet
  </portlet-class>
  <init-param>
    <name>default-view</name>
    <value>/stylesheets/welcome.jsp</value>
  </init-param>
  ...
</portlet>
"
&nbsp;&nbsp; &nbsp;xmlns:h="http://java.sun.com/jsf/html"
&nbsp;&nbsp; &nbsp;xmlns\:p="http://primefaces.prime.com.tr/ui">
<f:view locale="#{sessionController.locale}">
&nbsp;&nbsp; &nbsp;<head>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<\!-\- Commentaire \-->
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<title><h:outputText value="#{applicationService.name}" /></title>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<ui:repeat value="#{tagsConfigurator.stylesheets}" var="path">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<t:stylesheet path="#{path}" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</ui:repeat>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<ui:repeat value="#{tagsConfigurator.scripts}" var="path">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<script type="text/javascript" src="#{path}" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</ui:repeat>
&nbsp;&nbsp; &nbsp;</head>
&nbsp;&nbsp; &nbsp;<body class="fl-theme-app">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<ui:include src="_include/_header.xhtml" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div id="welcomepages">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div id="navigationHeader" class="app-pagebar">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<h:form id="nav_header" styleClass="app-form" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div class="app-body">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div class="app-navigation">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div class="app-content">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<t:htmlTag value="br" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<ui:insert name="allContent" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div style="clear:both;" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div id="navigationFooter"
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;class="fl-container-flex app-pagebar">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<h:form id="nav_footer" styleClass="app-form" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<div class="app-footer">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<h:outputText value="#{applicationService.name} " />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<h:outputText value="v#{applicationService.version} - " />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<h:outputText value="#{applicationService.copyright}" />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;</div>
&nbsp;&nbsp; &nbsp;</body>
</f:view>

</html>