Dans la suite de cette page, les instructions que vous devez suivre sont indiquées comme suit :
instructions à suivre !
Introduction
L'application de commande en ligne eMarket dispose maintenant de quelques pages web et de règles de navigation, mais son contenu est purement statique. L'objectif de cette étape est de rendre le contenu des pages dynamique en utilisant des Beans, c'est-à-dire des composants Java.
Représentation des produits : JavaBean
Notre objectif est de peupler la page du catalogue catalog.xhtml avec des produits.
Pour le moment, nous allons faire comme si la base de données eMarket n'existait pas et fonctionner avec des produits qui ne seront pas persistants (pas sauvegardés en base). Les produits seront simplement représentés par des JavaBeans. Nous verrons un peu plus tard comment gérer la persistances des produits.
Dans le répertoire "Source" de votre projet, créer un package Java "model".
Dans ce package, créer une classe Java Product disposant de :
- un identifiant de type Integer ;
- un nom de type String ;
- un prix de vente de type Double.
Transformer cette classe Java en JavaBean en suivant les conventions liées aux JavaBeans : rendre la classe sérialisable, créer un constructeur par défaut, créer des accesseurs pour chacun des attributs (méthodes getX et setX pour chaque attribut X) !
Gestion du catalogue : ManagedBean
Il est maintenant nécessaire de faire le lien entre la page catalog.xhtml et les objets de type Product. Pour cela, nous allons utiliser la notion de ManagedBean de JSF.
En effet, une propriété intéressante d'un ManagedBean est que ses attributs et ses méthodes sont accessibles et utilisables directement dans les pages JSF (fichiers XHTML).
Création du bean
Dans le répertoire "Source" de votre projet, créer un package "logic".
Créer une classe Java CatalogManager dans ce package, avec un attribut permettant de stocker le catalogue, c'est-à-dire une liste d'objets de type Product.
Vous pouvez utiliser le type ArrayList<Product>.
Transformer votre classe Java en JavaBean en suivant les conventions liées aux JavaBeans.
Transformer votre JavaBean en ManagedBean en :
- l'annotant @ManagedBean (importer javax.faces.bean.ManagedBean) ;
- définissant la durée de conservation de son état (scope). Ici vous pourrez utiliser le scope "application" : @ApplicationScoped (importer javax.faces.bean.ApplicationScoped).
import javax.faces.bean.ManagedBean; import javax.faces.bean.ApplicationScoped; @ManagedBean @ApplicationScoped public class MyManagedBean implements Serializable{ ... }
Scope "application" : le scope "application" pour un bean signifie que son état est sauvegardé pendant toute la durée de vie de l'application. Par ailleurs, cela signifie également que cet état est partagé par tous les clients du bean. Ici, ce scope a été choisi parce que le catalogue peut être chargé en mémoire pour toute la durée de vie de l'application de commande en ligne et être partagé entre tous les internautes. Par contre, ce choix implique de faire attention à la mise à jour du catalogue chargé en mémoire dans le cas où un commercial ajoute un produit via l'application de gestion.
Utilisation du bean dans la page "catalog.xhtml"
Une fois le ManagedBean créé, il est possible de l'utiliser dans n'importe quelle page JSF en utilisant l'EL (Expression Language).
Informations sur l'Expression Language (EL)
L'Expression Language (EL) de JSF est un mini-langage qui permet d'accéder aux attributs et méthodes d'un ManagedBean depuis une page JSF. Dans une page JSF, toute expression écrite avec l'EL est mise entre #{ et }.
Voici quelques-un des principaux cas d'utilisation de l'EL :
Expression EL | Signification |
---|---|
#{unBean.unAttribut} | Retourne la valeur de l'attribut unAttribut du managed bean unBean |
#{unBean.unAttribut.unAutreAttribut.encoreUnAttribut} | L'EL n'impose pas une limite quant à la profondeur d'accès aux attributs, on peut donc appeler un attribut d'un attribut... |
#{uneValeur>25} | Retourne true si uneValeur est < 25. Les opérateurs suivants sont aussi supportés: <, <=, >, >=, ==, !=. |
#{uneValeur>25 and uneAutreValeur<10} | les EL supportent les opérateurs booléens: and, or et not. |
Ces cas d'utilisation peuvent être combinés pour construire des expressions plus complexes.
Attention à l'utilisation des majuscules/minuscules dans les expressions ecrites avec l'EL. Voici les règles à suivre :
- Pour faire appel à un ManagedBean dans une expression EL, il faut mettre la première lettre de son nom en minuscule. Exemple : si la classe de votre ManagedBean s'appelle "MyManagedBean", vous devez utiliser "myManagedBean".
- Pour faire appel à un attribut dans une expression EL, il faut que l'attribut dispose d'un getter et d'un setter. Puis pour faire appel à cet attribut il faut utiliser le nom du getter privé du préfixe "get" et avec la première lettre en minuscule. Exemple : si l'attribut dispose d'un getter appelé "getChoseMachin" et d'un setter appelé "setChoseMachin", vous devez utiliser "choseMachin" (quel que soit le nom réel de l'attribut).
Affichage du catalogue avec l'EL
Ici l'objectif est d'afficher le contenu du catalogue, donc la liste des produits, dans la page "catalog.xhtml". Le composant JSF permettant d'afficher une liste d'objets est la DataTable. Un exemple d'utilisation est donné ci-dessous. Dans cet exemple, le ManagedBean contient une liste d'objets de type Truc ayant deux attributs "x" et "y". :
@ManagedBean @ApplicationScoped public class MyManagedBean implements Serializable{ private ArrayList<Truc> myList; ... public ArrayList<Truc> getMyList(){...} public void setMyList(ArrayList<Truc> l){...} ... }
<h:dataTable value="#{myManagedBean.myList}" var="item"> <h:column> <h:outputText value="#{item.x}" /> </h:column> <h:column> <h:outputText value="#{item.y}" /> </h:column> </h:dataTable>
Utiliser le composant JSF DataTable pour afficher l'identifiant, le nom et le prix de vente des produits contenus dans le catalogue dans la page "catalog.xhtml".
Ajout de produits
Le catalogue du CatalogManager est vide pour le moment. Nous allons donc créer quelques produits et les ajouter au catalogue.
Créer une méthode "initCatalog" qui créée quelques produits et les ajoute au catalogue.
Pour que cette méthode soit appelée juste après la création du bean, l'annoter @PostConstruct.
@PostConstruct public void myInitMethod(){ ... }
Vérifier que les produits ainsi créés apparaissent bien dans la page "catalog.xhtml" en redéployant l'application sur le serveur.
Dans le cas où les produits n'apparaissent pas sur la page "catalog.xhtml" :
- Le code de votre ManagedBean contient peut-être des erreurs : vérifiez qu'il compile bien (NetBeans ne souligne pas en rouge le code), relisez ce que vous avez écrit pour éliminer les fautes de frappes.
Votre code droit ressembler à quelque-chose comme :
import javax.faces.bean.ManagedBean; import javax.faces.bean.ApplicationScoped; @ManagedBean @ApplicationScoped public class MyManagedBean implements Serializable{ private ArrayList<Truc> mylist; public MyManagedBean(){ this.mylist = new ArrayList<Truc>(); } @PostConstruct public void myInitMethod(){ Truc t = new Truc(); this.mylist.add(t); } ... }
- Fermez votre navigateur web ;
- Dans NetBeans allez dans l'onglet "Services > Servers", faire "clic droit" sur "GlassFish" et choisir "Stop".
- Fermez NetBeans.
- Relancez NetBeans.
- Redémarrez GlassFish (onglet "Services > Servers", clic droit sur "GlassFish" et choisir "Start").
- Redéployez l'application (clic droit sur le projet et choisir "Deploy" ou "Run").
Mise en page de la table (avancé)
Style de la table (avancé)
Il est possible d'améliorer l'apparence de la table des produits en utilisant CSS et le composant "f:facet" de JSF.
Utiliser CSS pour donner un style à la table. Il est possible :
- soit de définir un style général pour le tag HTML "table",
- soit d'associer une classe de style particulier à la table en utilisant l'attribut "styleClass" du tag JSF "h:datatable",
- soit d'associer des styles différents aux colonnes et aux lignes en utilisant les attributs "columnClasses" et "rowClasses" du tag JSF "h:datatable".
Ajouter des titres aux colonnes de la table en utilisant le composant facet "header" :
<h:column>
<f:facet name="header">Identifiant</f:facet>
<h:outputText value="#{item.id}" />
</h:column>
Composant "f:facet" : le rôle de ce composant est d'ajouter un élément optionnel au composant dans lequel il est inclu. L'attribut "name" désigne le type d'élément à ajouter. Certains composants JSF sont définis avec des éléments optionnels prédéfinis. Par exemple, le composant "h:column" peut être complété par deux types d'éléments optionnels : "header" et "footer". L'exemple ci-dessous montre le rendu HTML du composant "h:column" auquel a été ajouté l'élément "header" via un composant "f:facet" :
<h:dataTable id="idTable" value="#{bean.list}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="My Header" />
</f:facet>
<h:outputText value="#{item}" />
</h:column>
</h:dataTable>
<table id="idTable">
<thead>
<tr><th>My Header</th></tr>
</thead>
<tbody>
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
<tr><td>Item 3</td></tr>
</tbody>
</table>
Affichage conditionnel de la table (avancé)
Il est possible de faire en sorte que la table ne soit pas affichée dans la page catalog.xhtml lorsque la liste des produits est vide.
Définir une méthode "getCatalogSize" dans le bean CatalogManager qui rend la taille de la liste des produits.
Appeler cette méthode via l'EL dans l'attribut "rendered" du tag JSF "h:datatable" et comparer avec 0.
<h:dataTable value="#{bean.list}" var="item" rendered="#{bean.listSize > 0}">
De la même manière, il est possible de définir un texte qui sera affiché à la place de la table lorsque la liste des produits est vide.
Créer un composant "h:outputText" dont l'attribut "value" sera le message à afficher.
Utiliser l'attribut "rendered" de ce composant en comparant la taille de la liste des produits avec 0 (Remarque : l'opérateur de test d'égalité mathématique de JSF est "==").
Il est possible d'améliorer l'apparence de la table des produits en utilisant CSS et le composant "f:facet" de JSF.
Utiliser CSS pour donner un style à la table. Il est possible :
- soit de définir un style général pour le tag HTML "table",
- soit d'associer une classe de style particulier à la table en utilisant l'attribut "styleClass" du tag JSF "h:datatable",
- soit d'associer des styles différents aux colonnes et aux lignes en utilisant les attributs "columnClasses" et "rowClasses" du tag JSF "h:datatable".
Ajouter des titres aux colonnes de la table en utilisant le composant facet "header" :
<h:column> <f:facet name="header">Identifiant</f:facet> <h:outputText value="#{item.id}" /> </h:column>
Composant "f:facet" : le rôle de ce composant est d'ajouter un élément optionnel au composant dans lequel il est inclu. L'attribut "name" désigne le type d'élément à ajouter. Certains composants JSF sont définis avec des éléments optionnels prédéfinis. Par exemple, le composant "h:column" peut être complété par deux types d'éléments optionnels : "header" et "footer". L'exemple ci-dessous montre le rendu HTML du composant "h:column" auquel a été ajouté l'élément "header" via un composant "f:facet" :
<h:dataTable id="idTable" value="#{bean.list}" var="item"> <h:column> <f:facet name="header"> <h:outputText value="My Header" /> </f:facet> <h:outputText value="#{item}" /> </h:column> </h:dataTable>
<table id="idTable"> <thead> <tr><th>My Header</th></tr> </thead> <tbody> <tr><td>Item 1</td></tr> <tr><td>Item 2</td></tr> <tr><td>Item 3</td></tr> </tbody> </table>
Il est possible de faire en sorte que la table ne soit pas affichée dans la page catalog.xhtml lorsque la liste des produits est vide.
Définir une méthode "getCatalogSize" dans le bean CatalogManager qui rend la taille de la liste des produits.
Appeler cette méthode via l'EL dans l'attribut "rendered" du tag JSF "h:datatable" et comparer avec 0.
<h:dataTable value="#{bean.list}" var="item" rendered="#{bean.listSize > 0}">
De la même manière, il est possible de définir un texte qui sera affiché à la place de la table lorsque la liste des produits est vide.
Créer un composant "h:outputText" dont l'attribut "value" sera le message à afficher.
Utiliser l'attribut "rendered" de ce composant en comparant la taille de la liste des produits avec 0 (Remarque : l'opérateur de test d'égalité mathématique de JSF est "==").