Navigation dynamique [JSF] - Java - Programmation
Marsh Posté le 15-03-2010 à 13:17:05
Re-bonjour,
Ceci n'est pas un "up !", mais une réponse à moi-même.
J'ai trouvé une solution qui répondait à ma demande, et au cas où quelqu'un aurait les mêmes besoins que moi, au moins, il aura une solution possible.
Premièrement, je suis passé en JSF 2 (en prenant la version beta 2 de Jboss). Je me suis dit que pour un développement, une version beta pourrait suffire et comme l'application est assez conséquente à développer, il existera sans doute une version release au moment de mettre en production.
Donc, pour la maquette que j'ai faite, j'ai fait quelque chose de très simple : j'ai fait une procédure qui s'appelle "Carte d'identité", qui en fait, demande à l'utilisateur de saisir des informations sur lui (nom, prénom, date et lieu de naissance) puis de simplement afficher les informations saisies à la fin de la procédure. La saisie des informations a été faite en deux fois :
Dans cette maquette, j'ai deux types de managed beans :
Les FromBean :
Ces beans ont donc pour seule fonction de gérer une page avec un formulaire. Par exemple, le formulaire name.xhtml permet de saisir un nom et un prénom, grâce à deux zones de texte. Le formulaire possède un bouton valider, et un bouton annuler.
La classe abstraite FormBean force l'implémentation des méthodes public void submit() et public void cancel(). La méthode public void setListener(FormBean Listener listener) qui permet d'ajouter un "écouteur" sur le bean.
Les boutons valider et annuler appellent respectivement les méthodes submit() et cancel() du managed bean associé. Lorsqu'une de ces deux méthodes sont appelées, les écouteurs sont mis au courant.
Voici le code de la méthode public void submit() d'un managed bean de formulaire. A savoir que la méthode cancel() sera écrite sur le même principe.
Code :
|
Les FormBeanListener :
Cette interface demande à implémenter les méthodes onSubmit(FormEvent event) et onCancel(FormEvent event). Vous l'aurez sans doute deviné, ces méthodes seront appelées lorsque le visiteur aura cliqué sur valider ou annuler sur le formulaire écouté.
la classe FormEvent représente un événement de formulaire (submit ou cancel), qui contiendra les informations suivantes :
Un bean décrivant une procédure aura comme propriétés :
Pour démarrer une procédure, on appellera la méthode public String start() de notre bean IdentityProcBean, qui va s'ajouter en tant que listener sur le premier formulaire (name.xhtml), puis retourner l'url du premier formulaire. Le code sera donc :
Code :
|
.
Une fois le formulaire validé, la méthode onSubmit(FormEvent event) sera appellée. Le bean devra donc récupérer et stocker les données saisies, puis, devra demander l'affichage du deuxième formulaire. Le code de cette méthode sera donc :
Code :
|
Sur la méthode onCancel(FormEvent event), on peut par exemple écrire le code suivant, pour afficher un message comme quoi la procédure a été annulée :
Code :
|
.
Avec ceci donc, ça fonctionne très bien. Cela requiert JSF 2 pour avoir la possibilité de retourner directement l'URL dans des méthodes de beans. Le fichier web.xml ne sert donc plus du tout pour la navigation et chaque procédure peut donc utiliser, dans l'ordre qu'elle le désire, chaque formulaire.
Je suis à vous si vous avez des questions, remarques
Marsh Posté le 11-03-2010 à 18:27:13
Bonjour à tous,
Je développe actuellement une application J2EE hébergée sur JBoss AS 5.0, utilisant principalement Hibernate + EJB3 (pour le métier), JSF 1.2 + Richfaces 3.3 + Facelets pour la partie Web de l'application.
Je ne suis pas à ce jour un grand connaisseur de tous ces frameworks, mais je me suis beaucoup documenté à ce sujet.
J'ai bien intégré le fonctionnement des EJB (Entity et Session) avec les JSF (via des Managed Bean).
Là où est-ce que je bloque, c'est pour ma partie navigation entre les pages.
Afin d'illustrer ma question, je vais définir un exemple fictif.
Supposons que mon application gère plusieurs objets métier :
De façon simpliste, on admettra ces quelques règles de gestion :
Une fois les EJB (Entity et Session) implémentés, il est très simple d'implémenter les différentes pages suivantes :
Les formulaires pour l'ajout/modification :
Formulaire d'identification pour l'espace membre :
Pages d'accueil :
Puis les pages de listing :
Maintenant, prenons un ou deux workflows de l'application.
I - Workflow 1
Je ne suis pas "membre" de l'application et je veux enregistrer un projet dans l'application pour faciliter sa gestion.
Afin de créer le projet, nous avons besoin de plusieurs informations :
Afin de mieux comprendre l'intérêt de ma question, imaginez que la page d'accueil de l'application soit en fait une liste de liens avec toutes les procédures possibles. Cette liste sera disponible à tout le monde (membre identifié ou non).
J'arrive donc avec mon navigateur préféré sur la page d'accueil, je ne suis pas identifié. Je clique sur le lien "Créer un nouveau projet".
La procédure "Créer Projet" se met donc en route. L'application connait la liste des informations nécessaires pour pouvoir effectuer la création du projet.
(1) la page login.xhtml m'est affichée :
(1-a) Le formulaire editMember.xhtml m'est affiché, je le remplis, puis je retourne à l'étape (1)
(2) Le formulaire editProjet.xhtml m'est affiché je le remplis, mon nouveau projet est créé, je passe à l'étape (3)
(3) La page d'accueil du projet (homeProject.xhtml) est affichée
II - Workflow 2
Dans l'exemple I, je me suis créé un compte et j'ai maintenant un projet. Je viens d'arriver sur la page d'accueil de l'application et je voudrais créer une tâche pour mon projet.
C'est donc une nouvelle procédure qui s'appelle "Créer tâche", accessible via un lien présent sur la page d'accueil de l'application. Cette procédure aura donc besoin :
Je ne suis pas identifié sur l'application.
(0) Je clique sur le lien "Créer une tâche" depuis la page d'accueil de l'application.
La partie concernant l'information du membre est identique à l'exemple I. A partir de l'étape suivante, on admettra donc que l'on est identifié.
(1) La liste de mes projets est affichée (listProjects.xhtml) :
(1-a) la page editProjet.xhtml est affichée, je remplis le formulaire puis je valide
(2) J'arrive directement sur la page editTask.xhtml, qui me permettra d'ajouter une tâche pour le projet précédemment sélectionné. Je remplis le formulaire, puis valide, ma tâche est créée, fin de la procédure.
Ces deux exemples m'amènent cette question : est-il possible, et par quel moyen, de définir de tels workflows, en utilisant à chaque fois des pages de formulaires communes à plusieurs workflows ? Dans l'application, on pourrait accèder à chaque page unitairement en cliquant sur les liens proposés à chaque étape. Mais est-il possible de mettre en place des procédures qui enchaîneront les pages dans un ordre bien précis ?
J'ai regardé le système de navigation de base proposé par JSF 1.2, je n'ai pas trouvé de solution dans celui-ci. J'ai ensuite regardé ce que proposait JSF 2, et apparemment, les choses ont un peu changé, j'ai cru comprendre que les méthodes d'action des Managed Beans pouvaient retourner directement un view-id. La solution serait donc de créer un managed bean par procédure (workflow) et que les pages soient appelées dans l'ordre voulu grâce au retour des méthodes d'actions :
Avec pour exemple ceci : un managed bean MaProcédure1 qui possède les différentes action-methodes suivantes : doAction1(), doAction2(), doAction3() et la méthode 1 retournerait le view-id de la page pour l'action2, etc.
Le truc qui gênent dans cette solution, c'est que :
Ca fait un très long TOPIC, merci d'avoir lu jusqu'ici, mais je voulais être le plus clair possible pour poser ma question.