1 / 54

Jboss Seam & Seam Hotel Booking

Jboss Seam & Seam Hotel Booking. Sommaire. Jboss Seam Présentation générale Les composants Seam Un modèle de programmation contextuelle Bijection dataModel Intégration JSF/EJB3 Validation des formulaires Navigation Le cycle de vie Seam Hotel Booking Présentation de l’application

preston
Download Presentation

Jboss Seam & Seam Hotel Booking

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Jboss Seam & Seam Hotel Booking

  2. Sommaire • Jboss Seam • Présentation générale • Les composants Seam • Un modèle de programmation contextuelle • Bijection • dataModel • Intégration JSF/EJB3 • Validation des formulaires • Navigation • Le cycle de vie • Seam Hotel Booking • Présentation de l’application • Authentification • Recherche • Conversation • Sécurité • Navigation

  3. Jboss Seam

  4. Présentation générale • Framework Open Source développé par Jboss et initié par Gavin King, le père d’Hibernate • Conteneur léger J2EE • Seam est l’un des premiers Framework à supporter les architectures avec état grâce à la notion de conversation • Il utilise un modèle de programmation POJO

  5. Présentation générale • Seam intègre de nombreuses technologies : • Le standard JSF ainsi que les composants graphiques RichFaces, IceFaces (composants graphiques riches), et Ajax4JSF (extension Ajax des composants JSF de base) • Seam Remoting : API JavaScript permettant d'accéder depuis le navigateur à un composant Seam coté serveur • Le standard EJB stateless et stateful d’EJB3 (pour les composants conversationnels) • Le standard JPA et les entités d'EJB 3 pour la persistance • JBoss Drools : sécurité déclarative par règles

  6. Présentation générale • JBoss jBPM : processus fonctionnels et workflows • Support de GWT (Google Web Toolkit) • Les web services (possibilité d’utiliser un composant Seam en tant que web service) • Hibernate Search • Itext : génération de PDF • TestNG : framework pour faciliter la création de tests unitaires • …

  7. Présentation générale

  8. Les composants Seam • Les composants prennent en charge les fonctionnalités et la logique métier de l’application web • Ils permettent également de gérer des événements de la couche « vue » ou d’intéragir avec la base de données • Ce sont des objets POJOs • Les composants sont définis par 3 éléments : Le nom, la portée et le rôle (gérés par des annotations)

  9. Les composants Seam • Les composants Seam sont associés à des variables du contexte grâce à l’annotation @Name. Cette déclaration correspond à la balise <managed-bean-name> issue du fichier « faces-config.xml  ». Le nom du composant doit être unique dans le système • Un composant Seam est obligatoirement déclaré dans un contexte : • Soit de manière implicite (en fonction du type de composant) • Soit de manière explicite en précisant le scope à l’aide de l’annotation @Scope

  10. Les composants Seam • Un composant peut être rattaché à plusieurs variables de contexte. Le couple d’annotations @Name/@Scope permet de définir un « rôle » par défaut. Il est possible de l’enrichir en ajoutant de nouveaux « rôles » grâce à @Role(name=, scope=) ou @Roles({@Role(), @Role()}) • Seam admet 5 types de composants : • Stateless session bean (scope par défaut : STATELESS) • Stateful session bean (scope par défaut : CONVERSATION) • Entity bean (scope par défaut : CONVERSATION) • JavaBean (scope par défaut : EVENT) • Message-driven beans

  11. Les composants Seam • Le cycle de vie d’un composant peut être géré par les annotations @Create et @Destroy (redéfinition des annotations @PostConstruct et @Predestroy): • @Create : Une méthode annotée de @create sera appelée immédiatement après la création du composant • @Destroy : Une méthode annotée de @destroy sera appelée avant la destruction du contexte

  12. Les composants Seam @Scope(ScopeType.SESSION) @Name("MyDatabaseUtils") Public class MyDatabaseUtils{ @Create public void initDatabase(){ } @Destroy public void closeDbResources(){ } }

  13. Un modèle de programmation contextuelle Ordre de priorité de recherche • Seam introduit de nouveaux contextes : • Event : C’est le plus « petit » contexte de Seam. Un composant associé à un contexte « Event » est détruit à la fin de la requête • Page : Un composant associé à un contexte « Page » est lié à une page spécifique. L’état est stocké sur le client • Conversation • Session : Le composant est géré comme un objet en session HTTP • Process • Application : Le composant associé au contexte « Application » est disponible du début à la fin de l’application. Ce contexte peut s’avérer utile pour le maintien d’informations statiques utiles à plusieurs composants

  14. Un modèle de programmation contextuelle : La conversation • La Conversation : • Une conversation représente généralement une multitude de requêtes qui proviennent du même client • Permet de simplifier la gestion de la Session HTTP. Le contexte de conversation permet de résoudre les problèmes suivants : • Le client ne termine pas la transaction • Le navigateur du client n'accepte pas les cookies • Le client ouvre un autre navigateur et lance une autre action (achat par exemple) • Le client clique sur le bouton Back de son navigateur • Permet de contrôler la durée de vie d’un composant

  15. Un modèle de programmation contextuelle : La conversation • Une conversation est attachée à UN onglet ou à UNE fenêtre d’un navigateur  Un utilisateur peut « gérer » plusieurs conversations (donc plusieurs espaces de travail) en même temps sans que celles-ci ne rentrent en « collision » • Il existe 2 types de conversations : • La conversation implicite (ou conversation temporaire) : • Créée par défaut pour chaque requête • Elle démarre à la soumission de la requête et se termine au rendu de la réponse • La conversation explicite (ou conversation longue) : • Créée de manière déclarative (utilisation des annotations @Begin et @End) au niveau de l’application • Permet d’étendre une conversion temporaire en une conversion longue • Non détruite une fois la page de réponse rendue

  16. Un modèle de programmation contextuelle : La conversation Implicite Explicite Par défaut Java pages.xml @Begin / @End JSF Page f:param conversationPropagationou @propagation in seam:link-Element

  17. Un modèle de programmation contextuelle : Process • Le contexte « Process  » : • Permet l'intégration de la gestion des processus métiers dans une application. • Il est géré par un moteur BPM (Business Process Management, ici, JBPM). • Il est multi-utilisateur • Il peut subir de nombreuses interactions

  18. Un modèle de programmation contextuelle Application Process Session Request Request Request Conversation Conversation Session Request Request Request Conversation Conversation

  19. Bijection @In et @Out • Seam propose un mécanisme d'injection des dépendances dynamique et bijective  cela permet une interaction entre composant • Mécanisme à base d’annotation (pas de fichier XML) • Un composant peut être injecté automatiquement dans un autre composant (@In) • Un composant peut également créer et projeter un autre composant dans le contexte (@Out)

  20. Bijection @In et @Out • Il est possible de forcer la création d’un composant au moment de l’injection (@In(create=true)) • Il est possible de projeter un composant en redéfinissant son scope (@Out(scope=ScopeType.SESSION)) • Seam crée le composant si il n’existe pas et gère son cycle de vie  "Inversion of Control" (IoC)

  21. Bijection@In et @Out @Stateful @Name("hotelBooking") public class HotelBookingAction implements HotelBooking { @In private User user; @In @Out private Hotel hotel; … }

  22. Bijection@Factory • @Factory (factory data provider): permet d’initialiser une variable d’un composant Seam à la 1ère demande. En effet, @Factory vérifie que celle-ci est bien initialisée lorsque la couche de présentation demande l’objet mais ne la réinitialise pas si une donnée a été changée • L’annotation @Factory peut être utilisée de 2 manières : • Sur une méthode renvoyant void • Sur une méthode ne renvoyant pas void. Dans ce cas, il faut être attentif au scope : • Si le scope n’a pas été défini de manière explicite, la variable obtient le scope du composant • Si le scope du composant est défini à « Staless » et que le scope n’a pas été défini de manière explicite, le scope par défaut est « Event » • Dans les 2 cas : • La variable sera initialisée si celle-ci ne contient pas de valeur • Elle sera exposée dans le contexte avec le nom défini en paramètre de l’annotation @Factory

  23. DataModel • @DataModel et @DataModelSelection sont directement liés à l’utilisation du composant JSF « dataTable » • @DataModel : Projette un attribut du type List, Map, Set ou Object[] et le convertit en une instance de DataModel (permet de récupérer l’élément actif à partir de la méthode getRowData()) • @DataModelSelection : Permet de conserver l’objet de la ligne courante d’une « dataTable ». Il est également possible de passer celui-ci directement dans une expression EL Objet courant <s:link value="View Hotel" action="#{hotelBooking.selectHotel(hot)}" />

  24. DataModel • Utilisation des annotations @DataModel, @DataModelSelection et @Factory @DataModelprivate List <Person> fans; @DataModelSelection private Person selectedFan; @Factory("fans") public void findFans () { fans = em.createQuery("from Person").getResultList(); } public void delete () { em.remove(selectedFan); } Variable exposée dans le contexte La variable « fans » sera initialisée lors du 1er appel de la page Utilisation de l’objet courant

  25. Intégration JSF/EJB3 • Jboss Seam implémente la JSR-299 (Web Beans) : Principe qui consiste à standardiser l’unification de 2 modèles de composants (JSF et EJB3). Permet de simplifier le modèle de programmation des applications Web • Disparition du Managed Bean et du fichier de configuration « faces-config.xml » • Composant métier invoqué directement depuis la page JSF via L'Expression Language

  26. Intégration JSF/EJB3 <h:commandButton value="Register" action="#{register.register}"/> @Stateful @Name("register") public class RegisterAction implements Register{ @In private User user; @PersistenceContext private EntityManager em; public void register(){ em.persist(user); }}

  27. Intégration JSF/EJB3 EJB3 Session Bean EJB3 Session Bean Page JSF Managed Bean Page JSF EJB3 Entity Bean EJB3 Entity Bean JSF et EJB3 : Approche « classique » JSF et EJB3 avec Jboss Seam

  28. Intégration JSF/EJB3 JSF Page POJO Facade Session EJB Entity EJB POJO Facade JSF Page Managed Bean Session EJB JSF Page JSF Page Entity EJB

  29. Validation des formulaires • Seam utilise le Framework « Hibernate Validator » pour effectuer la validation des contraintes à un seul endroit : le modèle de données • Evite la duplication des règles de validation sur les différentes couches (présentation, persistance, base de données, …) • Une vingtaine de contraintes prédéfinies avec la possibilité d’en créer d’autres (par implémentation de la classe Validator)

  30. Validation des formulaires

  31. Validation des formulaires @Entity @Name("hotel") public class Hotel { private String name; @Length(max=50)@NotNull public String getName() { return name; } } <f:form> <s:validateAll> <h:inputText value="#{hotel.name}"  /> </s:validateAll> </f:form> Permet de valider les champs du formulaire en utilisant Hibernate Validator

  32. Validation des formulairesLes messages d’erreurs • 2 façons de gérer les messages d’erreurs : • En utilisant les standards JSF (la balise <h:message>. Cette balise ne rend qu’UN message. Possibilité d’afficher l’ensemble des messages en utilisant <h:messages>) • En utilisant l’approche Seam et sa balise <s:decorate> (plus complexe mais permet une meilleur gestion de l’affichage) • Il est possible de gérer un message d’erreur pour chaque champ. Pour cela, il est nécessaire de préciser l’identifiant du champ dans la balise « for » <h:inputText id="name" value="#{person.name}"/> <h:message for="name" />

  33. Validation des formulairesLes messages d’erreurs • Dans le cas de l’utilisation des annotations du Framework Hibernate Validator : • En cas de violations de contrainte, l'exception « InvalidStateException » est levée  création d’un tableau « d’InvalidValues » décrivant chaque échec • (Hypothèse) Le tableau retourné ne contient que les erreurs du champ concerné (via la méthode getInvalidValues()), les messages sont ajoutés au contexte (via la méthode addMessage()) et ceux-ci sont affichés au niveau de la couche présentation par la balise <h:message>

  34. NavigationModèles de navigation • Il existe 2 modèles de navigation : • Le modèle de navigation sans état (stateless navigation model) • Règles standards de navigation de JSF • Règles de navigation de Seam • Le modèle de navigation avec état (stateful navigation model) : • jPDL

  35. Navigation stateless navigation model • Renvoi d’une chaine de caractères (correspondant au nom de la page) avec possibilité de passage de paramètres • Utilisation des règles standards de navigation de JSF (fichier de configuration « faces-config.xml »). Cette méthode présente quelques limitations : • Impossible de définir des paramètres lors d’une redirection • Impossible de démarrer ou de finir une conversation • Impossible d’évaluer une EL expression (seulement la valeur de retour d’une méthode) public String search() { return "/results.jsp?pattern=#{searchAction.searchPattern}";}

  36. Navigation stateless navigation model • Utilisation des règles de navigation de Seam (définies dans le fichier « pages.xml »). Ce mécanisme permet : • D’utiliser des EL expression • De commencer ou terminer une conversation • De passer des paramètres Document source <page view-id="/editDocument.xhtml"> <navigation from-action="#{documentEditor.update}"> <rule if="…"> <end-conversation/> <redirect view-id="/viewDocument.xhtml"> <param name="id" value="#{documentEditor.documentId}"/> </redirect> </rule> </navigation> </page> Eventuelle condition Fin de la conversation Document destination Passage de paramètres

  37. Navigation stateful navigation model • Utilisation du langage de définition jPDL qui permet de décrire les différentes étapes par lesquelles doit passer un utilisateur pour réaliser une tâche • Le pageflow est composé d’états et de transitions • Il existe 2 sortes d’état : • Les décisions : permettent d'aiguiller la navigation en fonction de l'état du système. Chaque décision est associée à l'évaluation d'une expression (booléenne ou non) • Les pages : permettent d'aiguiller la navigation en fonction des actions de l'utilisateur • Les transitions permettent de passer d'un état à l'autre

  38. Navigation stateful navigation model <pageflow-definition> <decision name="has book?" expression="#{}"> <transition name="true" to="rejected" /> <transition name=« false" to=« enter ISBN" /></decision><page name="rejected" view-id=".xhtml"> <end-conversation /> </page>…<page name="confirm checkout" view-id=".xhtml"> <transition name="confirm" to="confirmed"> <action expression="#{beanManager.method()}"/> </transition> <transition name="cancel" to="enter ISBN"/> </page>…</pageflow-definition>0 Méthode retournant un booléen Termine une conversation Méthode associée à une transition <input type="submit" jsfc="h:commandButton" value="Confirm" action="confirm" /> <input type="submit" jsfc="h:commandButton" value="Cancel" action="cancel" />

  39. Le cycle de vie

  40. Seam Hotel Booking

  41. Présentation de l’application • Seam Hotel Booking est une application web de démonstration qui utilise les principaux concepts du Framework Jboss Seam (contexte conversationnel, intégration JSF/EJB3, …) • Elle permet : • De s’identifier • D’enregistrer un nouvel utilisateur • De rechercher un hôtel et d’en visualiser les détails • De réserver un hôtel (en précisant la date d’arrivée et de départ) • D’annuler une réservation • De visualiser les derniers hôtels sélectionnés (contexte de conversation)

  42. Authentification • Basé sur JAAS (Java Authentication and Authorization Service) : Framework de sécurité robuste et hautement configurable pour la gestion d’authentification utilisateur. Assuré par la classe org.jboss.seam.security.Identity • Le champ login est « bindé » avec « identity.username », password avec « identity.password » (2 attributs de la classe Identity) tandis que le bouton appelle la méthode « identity.login » (vérifie si l’utilisateur est déjà connecté) Attribut username Attribut password Méthode login()

  43. Authentification • L’application Seam Hotel Booking utilise sa propre méthode d’authentification. Elle permet simplement de vérifier que le couple login/password est bien présent dans la base de données • Cette méthode d’authentification doit être déclarée dans le fichier de configuration « components.xml » sous la forme suivante : • La méthode authenticate() renvoie un booléen : • True si le couple login/password (requête SQL) • False sinon <security:identity authenticate-method="#{authenticator.authenticate}"/>

  44. Recherche • La recherche d’un hôtel est paramétrée par un motif (attributs de l’entity bean « Hotel » : nom, adresse, ville ou code postal de l’hôtel) et par le nombre de réponses retournées (5, 10, ou 20) • Utilisation de la balise <a:support> pour le support AJAX  Permet de rafraîchir une zone (le résultat de la recherche) de la page à chaque événement JavaScript « onkeyup » (relâchement de la touche) Attribut searchString Méthode find() Attribut pageSize

  45. Recherche • Utilisation de la balise @DataModel afin d’exposer, au contexte, une liste d’hôtels (résultat d’une requête SQL) @PersistenceContext private EntityManager em; @DataModel private List<Hotel> hotels; public void find(){ hotels = em.createQuery("select h from Hotel h where … ").getResultList(); }

  46. Recherche • Utilisation du composant JSF « dataTable » pour afficher la variable « hotels » (liste des hôtels trouvés suite à la recherche) Panel rafraîchi lors de l’action « onkeyup » Liste à afficher Valeur de l’objet courant <a:outputPanel id="searchResults"> <h:dataTable id="hotels" value="#{hotels}" var="hot" rendered="#{hotels.rowCount>0}"><h:column><f:facet name="header">Name</f:facet> #{hot.name} </h:column> </h:dataTable></a:outputPanel> Condition de rendu Valeur de la colonne Entête de colonne

  47. Conversation • Dans le cadre d’une réservation d’hôtel, l’achat DOIT se dérouler en 5 phases : • Phase 1 : l'utilisateur doit effectuer une recherche afin de sélectionner un hôtel. La conversation commence seulement au moment où l’utilisateur clique sur l’action « View Hotel  », action rattachée à une méthode annotée par @Begin Résultat d’une recherche

  48. ConversationPhase 1 <s:link value="View Hotel" action="#{hotelBooking.selectHotel(hot)}" /> Déclaration du composant « hotelBooking » @Stateful@Name("hotelBooking") public class HotelBookingAction implements HotelBooking{ @PersistenceContext(type=EXTENDED) private EntityManager em; @In(required=false) @Out private Hotel hotel; @Begin public void selectHotel(Hotel selectedHotel){ hotel = em.merge(selectedHotel); }} Permet d’injecter un EntityManager Gestion du mécanisme de bijection Permet de débuter une conversation longue

  49. ConversationPhase 2 • Phase 2 : L’utilisateur accède au détail de l’hôtel qu’ il vient de sélectionner. Cette page lui permet de continuer sa réservation ou de revenir à sa recherche initiale • Phase 3 : Demande d’informations pour la prise en compte de la réservation (date de début et de fin, nombre de lits, …) • Phase 4 : Récapitulatif de la réservation

  50. ConversationPhase 5 • Phase 5 : Confirmation de la réservation. Cette action fait appel à une méthode annotée par @End : Le contexte passe du statut de conversation longue à conversation temporaire. De plus, il y a enregistrement de la réservation dans la base de données

More Related