Pourquoi un bean de portée requête convient pour utiliser dans une page un nombre tapé dans une autre page ?

Pour le comprendre il faut se rappeler comment fonctionne le cycle de vie JSF.

Tout d'abord, rassurez-vous, le plus souvent on n'a pas besoin de détailler le cycle de vie JSF pour comprendre ce qui se passe. Cependant il faut pouvoir le faire dans les cas difficiles (mais rares) où on ne comprend pas pourquoi ce qu'on a écrit ne fonctionne pas bien. Je vais donc le faire ici sur ce cas très simple. Lisez attentivement pour vous assurer que vous avez bien compris le fonctionnement du cycle de vie JSF.

Quand l'utilisateur soumet le formulaire dans lequel il a tapé un nombre, une requête POST est envoyée au serveur. Cette requête POST contient le nombre tapé par l'utilisateur dans le formulaire, sous la forme d'une chaîne de caractères.

A l'arrivée sur le serveur toutes les phases du cycle de vie JSF sont exécutées.

Restore View : La vue qui correspond à la page formulaire_1 est restaurée. Cette vue est composée de composants JSF, en particulier du composant qui correspond au champ de saisie du nombre. La valeur que ce composant avait au moment de l'affichage de la page est conservée dans une variable interne.

Apply Request Value : La valeur tapée par l'utilisateur est conservée sous la forme d'une String dans la même variable interne de ce composant.

Une instance de Bean est créée automatiquement par JSF à cause de #{bean.nombre} du code de la page JSF.

Process Validations : Commence par la conversion du nombre en int. Pourquoi ? Parce que la valeur tapée par l'utilisateur correspond à l'expression EL #{bean.nombre}, que bean est le nom associé à la classe Bean et que cette classe Bean a une propriété nombre de type int (getNombre() retourne un int, setNombre prend un int en paramètre).

Si la conversion ne peut être faite, par exemple si l'utilisateur a tapé "rre", la page du formulaire est retournée, avec les éventuels messages d'erreur, et le cycle de vie se termine.

On suppose que la conversion s'est bien passée : l'utilisateur a bien tapé un nombre.

Il n'y a pas d'autres valeurs à convertir. On passe donc à la validation des données.

Il n'y a pas de validation à effectuer, donc la phase s'arrête là.

Update Model Value : Le nombre est mis dans la propriété "nombre" de la classe Beans en utilisant la méthode setNombre (à cause de l'expression EL #{bean.nombre}.

On est toujours en train de traiter la même requête donc bean est bien représenté par l'instance de Bean créée au début (ce bean a une portée requête donc il ne sera supprimé qu'à la fin du traitement de la requête).

Invoke Application : Pas de méthode action à exécuter (action="affichage_1") donc on passe à l'étape suivante en sachant que la page à retourner à l'utilisateur est la page affichage_1.

Render Response : La vue qui correspond à affichage_1 est créée et ensuite codée en HTML. Cette page contient plusieurs expressions EL. #{bean.nombresSuivants} utilise la même instance de Bean car on est toujours dans la même requête. La méthode getNombresSuivants() de Bean est utilisée pour avoir la valeur de la propriété nombresSuivants. Cette méthode utilise la variable d'instance "nombre" qui a reçu la valeur tapée par l'utilisateur dans la phase "Update Model Value". Si l'utilisateur a tapé le nombre 10, les nombres 11 à 15 sont ajoutés à la liste, valeur de la propriété.

<ui:repeat> est remplacé par la chaîne de caractères "11, 12, 13, 14, 15" et la page est retournée à l'utilisateur.

L'instance de Bean créée au début est supprimé puisque le traitement de la requête est terminée.

Voici donc pourquoi ça marche : c'est le même bean qui est utilisé pour ranger la valeur tapée par l'utilisateur dans la page formulaire_1 et pour afficher les nombres dans la page affichage_1.

Une question pour voir si vous avez bien compris :

Pourquoi lorsqu'on revient dans la page formulaire_1 pour saisir un autre nombre, la valeur précédemment saisie ne s'affiche pas ? Je pense que vous pouvez répondre, non ? Réponse.