TP2 2011 EJB 3.1 / JSF2

De $1

Version de 05:10, 7 Mai 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

Dans cette séance :

  • Exercices pour comprendre le modèle de navigation de JSF (je reprends ici une partie d'un TP de R.Grin, original sur : http://deptinfo.unice.fr/~grin/mescours/web-entreprise/tp/tpprg/),
  • Etude d'une correction du TP1 qui corrige les problèmes évoqués à la fin du TP1, notamment en mettant en oeuvre un Backing Bean de portée View.
  • Début du TP long à rendre sur un gestionnaire de comptes bancaires. Pour les nouveaux n'ayant pas suivi ce cours l'an dernier, vous verrez notamment comment créer une base de données à partir de zéro pour l'intégrer dans votre application.

 

Première partie : étude du modèle de navigation PRG (Post Redirect Get)

Objectifs de cette partie :

  1. Présenter les problèmes du POST utilisé par défaut par JSF, vus dans le TP1,
  2. Présenter le modèle PRG qui permet d'éviter la double soumission des formulaires et de pouvoir garder un marque-page des pages affichées.

Important : dans ce TP vous utiliserez des backing bean de portée "Requête". Il faut toujours essayer de limiter au maximum la portée des beans pour éviter l'encombrement de la mémoire (ce qui peut être un problème pour les sites Web très fréquentés). Evidemment dans certains cas, la portée "Session" est la plus indiquée (par ex pour un backing bean qui gère les connexions par login/password).

Exemple 1 : analyse d'un post tout simple

Nous allons étudier une application qui contient 2 pages JSF qui se référencent :

  • index.xhtml (point d'entrée de l'application Web) qui contient un formulaire avec champ de saisie d'un entier ; la soumission du formulaire passe la main à page2.xhtml,
  • page2.xhtml qui affiche les 5 nombres qui suivent le nombre saisi et qui contient un lien pour revenir vers la page index.html

Vous créerez un nouveau projet de type Web Application. Utilisez simplement le menu "new/JSF Page" pour créer les pages. 

Voici le code des deux pages en question :

Index.xhtml 

<?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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>Test 1</title>
    </h:head>
    <h:body>


     <h:form>
        <h:outputLabel value="Entrez un nombre" for="nombre"/>

        <h:inputText id="nombre" value="#{bean.nombre}"/>

        <h:commandButton value="Valider" action="page2"/>

      </h:form>

    </h:body>
</html>

page2.xhtml

<?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:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>Afficher des nombres</title>
    </h:head>
    <h:body>
        Les nombres : <br/>
        <ui:repeat value="#{bean.nombresSuivants}" var="n">

            #{n},
        </ui:repeat>
        <h:form>
        <h:commandLink action="index" value="Saisir un autre nombre"/>
        </h:form>
    </h:body>
</html>

Ces pages utilisent un Backing Bean (son nom est "bean") pour stocker la propriété correspondant au champs de formulaire "nombre". C'est la ligne suivante dans index.html qui correspond à la propriété :

/div[2]/div/pre[3], line 1, column 1: EOF expected

Voici donc le code du backing bean (que nous avons, dans cet exemple, mis dans le package "jsf") :

Bean.java

package jsf;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;

@Named(value = "bean")
@RequestScoped
public class Bean {

    private int nombre;

    public int getNombre() {
        return nombre;
    }

    public void setNombre(int nombre) {
        this.nombre = nombre;
    }

    public List<Integer> getNombresSuivants() {
        int nb = 5;
        ArrayList<Integer> t = new ArrayList(nb);
        for (int i = nombre; i < nombre + nb; i++) {
            t.add(i);
        }
        return t;
    }
}

Regardez déjà comment cet exemple s'articule. Notez dans les pages JSF l'utilisation de <ui:repeat ... /> qui correspond au tag JSTL vu l'an dernier <c:foreach... />. Notez que la collection sur laquelle on itère, donnée par :

/div[2]/div/pre[4], line 1, column 7: ":" expected

correspond encore à un accès à une propriété, la propriété "nombresSuivants" qui existe puisqu'une méthode getNombresSuivants() existe. Rappelons que ce sont les getters et setters qui définissent une propriété et non pas l'existence d'une variable d'instance dans la classe. En particulier ici on a pas de variable d'instance.

Exécutez cet exemple :

  • Testez en entrant autre chose qu'un nombre entier (un message doit s'afficher si vous avez bien écrit votre application),
  • Essayez de faire afficher au début dans la zone de saisie le nombre entré précédemment quand vous saisissez un nouveau nombre.

Remarquez-vous des anomalies quant à l'URL affiché par le navigateur ?

Rechargez la page qui affiche les 5 nombres. Que fait le navigateur ? Expliquez.

Est-ce possible de mettre un signet sur la page 2 pour un certain nombre. Par exemple 5 ; la page 2 affichera les nombres 6 à 10 qui sont censés représenter une information importante sur le nombre 5...

Et oui, cela ne marche pas ! Ce TP étudie un modèle, appelé PRG, pour ne plus avoir ce genre de problème.