ObjectWeb - Wiki - Main - frnotes Notes des enseignants 2006-2007 Notes des enseignants 2006-2007 • • • • • • • • 13/11 : Gestion des dépôts de fichiers (upload) 13/11 : CSS (Cascading Style Sheets) 13/11 : A propos de HttpSession 13/11 : Etapes de développement de la partie présentation 13/11 : Architecture et intégration de la couche présentation 13/11 : Livres gratuits sur les EJB 26/10 : Une autre application pour visualiser/administrer la BD 25/10 : Détails sur les session beans ° Problème d'exécution d'un script sous Unix ou Linux ° Front-end pour la BD ° Gestion de persistence (fichier persistence.xml) 13/11 : Gestion des dépôts de fichiers (upload) Certains groupes nous ont posé des questions pour la mise en oeuvre d'une fonctionnalité de dépôt de fichiers (par exemple pour ajouter des images correspondant à de nouveaux produits). Quelques pistes sont décrites ci-dessous. Notez cependant qu'il s'agit d'une fonctionnalité "annexe" par rapport au cahier des charges et qu'il est recommandé de travailler en priorité sur la couche présentation. 1) utiliser la classe http://servlets.com/cos/javadoc/com/oreilly/servlet/MultipartRequest.html presentée dans le livre de Hunter (Java Servlet Programming - OReilly) et distribuée dans http://servlets.com/cos/ 2) utiliser les EMB (http://jonas.objectweb.org/current/doc/howto/JOnASEmbHowTo.html) dont un exemple est fourni dans JONAS_EXAMPLE de la distribution standard de JOnAS. L'exemple fourni contient une servlet d'upload. Cela nécessite peu plus d'investissement mais peut être utile par la suite, notamment aux spécialistes en IHM (par exemple pour faire adapter Ecom à des clients de type PDA). 3) Pour le client lourd Java, utiliser RMI (et éventuellement les EMB). Il faut penser a passer le type MIME et l'identifiant du fichier. 13/11 : CSS (Cascading Style Sheets) Par manque de temps, cet aspect n'a pas été abordé en cours. L'utilisation des feuilles de style CSS est néanmoins recommandée. Le site ZenGarden est une bonne source d'exemples et de références : -1- ObjectWeb - Wiki - Main - frnotes http://www.csszengarden.com 13/11 : A propos de HttpSession Permet de faire survivre des données entre plusieurs requêtes http successives. L'HttpSession est en général associé à un timeout coté serveur. Une application bien programmée doit normalement détruire l'HttpSession quand le client se délogge explicitement. Il est nécessaire d'enregistrer un listener sur la session pour libérer les ressources à l'expiration du timeout. http://www-adele.imag.fr/users/Didier.Donsez/cours/servletjsp.pdf#page=45 Dans tous les cas, si le client ferme son navigateur, son HttpSession sera perdu car le cookie associé qui le référence sur le site client sera détruit lors de cette fermeture. Il est possible cependant de positionner des cookies afin de traquer l'usager sur plusieurs sessions (login persistant de wikipedia par exemple) http://www-adele.imag.fr/users/Didier.Donsez/cours/servletjsp.pdf#page=38 Remarque à propos des « cookies » de session : la session peut aussi être gérée par réécriture d'URL car les cookies peuvent être désactivés sur le navigateur du client: http://www-adele.imag.fr/users/Didier.Donsez/cours/servletjsp.pdf#page=39 13/11 : Etapes de développement de la partie présentation On favorise un développement incrémental. Dans une première étape, on définit un contrôleur mis en œuvre par une servlet globale avec délégation des actions vers des classes spécifiques. On définit des vues (JSP) globales, c.a.d qui affichent des pages HTML complètes. Dans une deuxième étape, des vues partielles seront définies (correspondant à des fractions de pages HTML) pour exploiter la technologie Ajax. Il faudra également ajouter des nouveaux types de requêtes http pour manipuler ces vues partielles. 13/11 : Architecture et intégration de la couche présentation On conseille l'usage des DTO (Data Transfer Objects) pour les échanges entre la couche métier et la couche présentation (plutôt qu'une solution basée sur le principe attach/detach). Autrement dit, on privilégie un passage des objets par valeur plutôt que par référence. Cela permet d'avoir une indépendance entre les représentations des données utilisées au niveau de chaque tiers. La traduction des structures de données échangées entre le tiers métier et le tiers présentation est effectuée au niveau des session beans. La convention de programmation est de terminer le nom d'une classe représentant un DTO par le suffixe DTO. -2- ObjectWeb - Wiki - Main - frnotes En général, ces classes sont référencées dans les interfaces des beans sessions façades du tiers métier. Les DTO peuvent être le format de représentation utilisés au niveau du tiers de présentation. Dans ce cas, ils sont utilisés par le contrôleur pour transmettre des données à la vue après avoir par exemple interagit avec la partie modèle. Cependant, il est conseillé d'utiliser une représentation propre au niveau du tiers présentation pour avoir une indépendance plus forte entre les tiers. Le DTO n'est qu'un format d'échange. Les DTO ne sont alors manipulés que dans la partie Modèle. Cette partie est un représentant du tiers métier qui « encapsule » toutes les communications avec les EJB ou les POJO. La partie Vue ne communique alors jamais directement avec le tiers métier, car elle s'adresse toujours à la partie Modèle pour ce faire. Le schéma ci-dessous résume l'architecture proposée pour le lien entre tiers présentation et tiers métier. Noter qu'en pratique, l'implémentation de la partie Modèle est réalisée par les appels aux beans façades depuis la servlet contrôleur. Quelques références sur les DTO : http://java.sun.com/blueprints/patterns/TransferObject.html http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html http://www.theserverside.com/tt/articles/article.tss?l=XMLBusinessDelegate 13/11 : Livres gratuits sur les EJB Mastering EJB 3.0 et EJB Design Patterns Disponibles sur theserverside.com (inscription gratuite requise) : http://www.theserverside.com/tt/books/wiley/masteringEJB3/index.tss -3- ObjectWeb - Wiki - Main - frnotes http://www.theserverside.com/books/wiley/EJBDesignPatterns/index.tss 26/10 : Une autre application pour visualiser/administrer la BD DbVisualizer 25/10 : Détails sur les session beans Si vous vous posez encore des questions sur le rôle des sessions beans et sur la différence entre stateful et stateless session beans, vous pouvez regarder ces explications sur le site de Sun. Plus généralement, ce (très gros) tutorial a aussi d'autres sections intéressantes, notamment sur les interfaces local/remote, la persistance et les transactions (voir parties III et IV). Problème d'exécution d'un script sous Unix ou Linux Si votre script shell ecom_setenv, ne s'exécute pas, il peut s'agir d'un souci d'encodage. Le fichier ecom_setenv.bat crée sous windows apparemment utilise un encodage DOS qui fait apparaître des caractères mal interprétés dans le shell. pour convertir le fichier dans vim, il faut faire la commande ":set ff=unix" Front-end pour la BD Une petite application d'administration/visualisation est fournie avec HSQLDB (HSQL Database Manager). Pour la lancer : java -cp %JONAS_ROOT%libcommonsjonashsqldb.jar org.hsqldb.util.DatabaseManagerSwing Et utiliser les paramètres suivants pour la connexion : Driver: org.hsqldb.jdbcDriver URL: jdbc:hsqldb:hsql://localhost:9001/db_jonas User: jonas Password: jonas Gestion de persistence (fichier persistence.xml) Pour avoir des données véritablement persistantes, penser à modifier le fichier etc/persistence.xml au niveau de la propriété "hibernate.hbm2ddl.auto". Remplacer la valeur "create-drop" (utile pour le debug) par "update". Extraits de la doc Hibernate/JBoss : "hibernate.hbm2ddl.auto: Automatically validate or export schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly. eg. validate | update | create | create-drop " sémantique de "update"?: "Creates the database schema on deploy if it doesn't exist. Alters it if it has changed. Useful for when you want to generate database schema from entity beans" La BD est "stockée" dans ${JONAS_ROOT}/work/hsqldb/db_jonas.script Petit mémo pour faire des Entity persistants dans le TP ECOM… Tout d'abord, il faut activer la persistence. Pour çà, mettre un petit "persistence.xml" dans ecom/etc/, qui ressemble à ceci : <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0. name="entity"> <provider></provider> <jta-data-source>jdbc_1</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="a compléter"/> </properties> </persistence-unit> </persistence> Puis ajouter au build.xml de ecom/ ceci : -4- ObjectWeb - Wiki - Main - frnotes <!-- persistence.xml file is defined --> <property name="persistence.defined" value="true" /> Ensuite, ne pas oublier de rajouter des @Id à tous les Entity bean. Par exemple, dans ProductBean.java : @Id private int ref_; Bon, à partir de là, çà risque de compiler, et de ne pas se planter. Ensuite, un exemple de bean ProductBean simplifié : @Entity public class ProductBean implements java.io.Serializable {@Id private int ref_;private double prix_; private String descrip_;public ProductBean() { } public ProductBean(int ref, String descrip, double prix) { this(); setRef(ref); setDescrip(descrip); setPrix(prix); }public int getRef() { return ref_; } public void setRef(int ref) { ref_ = ref; }public double getPrix() { return prix_; } public void setPrix(double prix) { prix_ = prix; }public String getDescrip() { return descrip_; } public void setDescrip(String descrip) { descrip_ = descrip; } } Suite à quoi, on peut y accéder, par exemple créer un produit depuis le EcomAdminBean, comme suit : @PersistenceContext private EntityManager entityManager_ = null;// … public void createProduct(int productId, String productName, double productPrice, int productStoreId, String city){ProductBean p = new ProductBean(productId, productName, productPrice); entityManager_.persist(p); } Après, rien de plus facile que de l'utiliser depuis un client, par exemple ExternAdmin.java : EcomAdminRemote ecomAdminBean = (EcomAdminRemote) initialContext.lookup("ecom.beans.EcomAdminBean" + "_" + EcomAdminRemote.class.getName() + "@Remote");ecomAdminBean.createProduct(ref, descrip, prix, 0, null); Notes des enseignants 2006-2007 (fr) Creator: xwiki:XWiki.donsez Date: 2007/08/23 08:33 Last Author: xwiki:XWiki.donsez Date: 2007/11/07 11:29 Copyright (c) 2005-2006, ObjectWeb Consortium -5-