Dvelopper des applications WEB avec Struts Applications Struts
© Développer des applications WEB avec Struts Applications Struts 1
© Plan du cours • Rappels sur les composants Java pour le WEB – Servlets – JSP – Architecture d’un site Web Applications Struts 2 • • Présentation de Struts Développement Utilisation avancée Conclusion
© Les Servlets • • • Applications Struts 3 Présentation Cycle de vie Principe de fonctionnement Échange d’informations Gestion d’une session
© Présentation des servlets • Exécution de traitements sur un serveur suite à une requête d’un client • Prévu pour tout type de protocole avec une implémentation pour HTTP • Génération de pages dynamiques orientée sur une logique de traitement • Concurrent aux technologies : Applications Struts 4 – CGI – NSAPI / ISAPI
© Le principe Présentation Applications Struts 5 • Processus Java qui s’exécute côté serveur suite à une requête d’un client • Exploite les paramètres de la requête • Repose sur les classes de l’API servlet de l'environnement J 2 EE • S’exécute au sein d'un moteur de servlets couplé au serveur Web
© Fonctionnement Présentation Client Response Request Web Server Moteur de servlets Request Applications Struts 6 Application Java
© Moteurs de servlets Présentation • Les moteurs peuvent être directement intégrés aux serveurs Web ou ajoutés comme modules par la suite • Parmi tous les serveurs supportant les servlets, on peut noter : – Tomcat, Resin, JRun, BEA Weblogic Server, IBM Websphere, Oracle Application Server, . . . Applications Struts 7
© Cycle de vie d’une servlet Cycle de vie Chargement et initialisation Serveur Client Servlet Échange de données avec les clients Serveur Servlet Déchargement Serveur Applications Struts 8 Servlet
© Conteneur de servlet Cycle de vie Conteneur de servlet Thread Servlet init() Requête HTTP Affectation de la requête service() initialisation exécution du service Réponse HTTP destroy() Applications Struts 9 nettoyage
© Mise en oeuvre (1) Mise en oeuvre Applications Struts 10 • Le package javax. servlet contient des interfaces et des classes pour l’écriture de servlets • Une servlet hérite de la classe HTTPServlet qui elle-même implémente l’interface Servlet • La servlet peut redéfinir des méthodes de HTTPServlet qui correspondent à des requêtes HTTP classiques : service(), do. Get(), do. Post(). . .
© Mise en oeuvre (2) Mise en oeuvre Applications Struts 11 • Les méthodes de type do. Get() et do. Post() reçoivent en paramètre deux objets : – Un objet Http. Servlet. Request qui encapsule la requête du client (renseignée automatiquement par le moteur) – Un objet Http. Servlet. Response qui encapsule la réponse qui sera retournée au client (à renseigner dans le code de la servlet)
© public class Exemple. Servlet extends Http. Servlet { Mise en oeuvre /** * Réponse à une requête HTTP GET : retourne une simple page HTML */ public void do. Get ( Http. Servlet. Request request, Http. Servlet. Response response ) throws Servlet. Exception, IOException { Print. Writer out; String titre = "Exemple simple de document généré par une servlet"; // Renseigne la réponse sur le type du document retourné response. set. Content. Type( "text/html" ); // Récupère un flux sur la réponse afin d’y écrire la page out = response. get. Writer(); Ex 3 Applications Struts // Ecriture de la chaîne correspondant à la page HTML retournée out. println("<HTML><HEAD><TITLE>"); out. println( titre ); out. println("</TITLE></HEAD><BODY>"); out. println("<H 1>" + titre + "</H 1>"); out. println("<P>Cette page provient d’une servlet. "); out. println("</BODY></HTML>"); out. close(); } } 12
© Surcharge des méthodes Mise en oeuvre void init() Applications Struts 13 Generic. Servlet Appelée au chargement de la servlet : initialisation, lecture des fichiers de conf… void Generic. Servlet service() Appelée à chaque invocation de la servlet void Generic. Servlet destroy() Appelée au déchargement de la servlet : destruction de tous les objets créés
© Partage des données Mise en oeuvre • Chaque servlet n’est instanciée qu’une seule fois, il y a donc persistence des données entre deux appels de la servlet • La valeur d’un attribut de la classe dérivant d’Http. Servlet dépend des autres invocations (multi-threads) – => Il ne faut pas utiliser les attributs pour stocker des informations ! Client 1 Applications Struts 14 Client 2 Client 3 Servlet Client 4
© Echange d’informations Echange d'informations • Trois objets peuvent servir d’intermédiaires pour échanger des informations entre composants Web : – La requête – La session – L’ « application » • Ils se comportent comme des hashtables et disposent des méthodes : Applications Struts 15 – set. Attribute() – get. Attribute()
© La requête Echange d'informations • La requête est passée en paramètre de la méthode service() (ou do. Get(), do. Post()…) • On y récupère l'URL d’appel, les paramètres HTTP et la session utilisateur – get. Request. URL() – get. Parameter(String name) – get. Session() Applications Struts 16 • Elle peut être transmise à une autre servlet lors d’une délégation de traitement (forward) • On y place des objets servant à la génération de la réponse
© L’ « application » Echange d'informations • L’ « application » est un objet de la classe Servlet. Context récupéré à partir de la servlet Servlet. Context application = this. get. Servlet. Context(); Applications Struts 17 • L’ « application » est partagée entre tous les objets Web et tous les clients d’une même application Web • On y place les objets servant pour toute l’application (ressources…)
© La session Echange d'informations • La session peut être récupérée à partir de la requête Http. Session session = request. get. Session(); Applications Struts 18 • La session est liée à un client. Elle existe tant qu’elle n’a pas été détruite volontairement ou par un time out • On y place les objets servant durant toute la connexion du client (typiquement : un caddie)
© Les cookies Gestion de sessions • Permettent le stockage d’informations au niveau du client • Utilisation de la classe javax. servlet. http. Cookie – Création Cookie mon. Cookie = new Cookie("nom", "valeur"); response. add. Cookie(mon. Cookie); – Récupération Applications Struts 19 Cookie[] mes. Cookies = request. get. Cookies();
© URL Rewriting Gestion de sessions • Gestion des sessions pour des clients n’acceptant pas les cookies • Méthodes – Http. Servlet. Response. encode. URL() – Http. Servlet. Response. encode. Redirect. URL() out. println( "<tr>" +. . . + "<a href="" + response. encode. URL(mon. Lien) + ""> + books[i]. get. Title() + "</a> ); Applications Struts 20 • Utilise le session ID pour retrouver la session de l’utilisateur
© Déléguer des traitements Gestion de sessions • Possibilité de rediriger la requête HTTP sur une autre URL response. send. Redirect(<location>); • Possibilité de déléguer une partie de la réponse à une autre ressource : Ex 4 -6 Applications Struts 21 – Par inclusion : include() – Par délégation complète : forward() Servlet. Context ctx = get. Servlet. Context(); Request. Dispatcher rd; rd = ctx. get. Request. Dispatcher(<Relative. URLOf. JSP>); rd. include( <Request. Object>, <Response. Object> ); rd. forward( <Request. Object>, <Response. Object> );
© Les Java Server Pages • Dans ce chapitre, nous allons : – Présenter l’architecture des JSP – Comprendre la syntaxe JSP – Développer un exemple de JSP Applications Struts 22
© Présentation des JSP • Génération de pages dynamiques orientée sur une logique de présentation • Ce sont des scripts interprétés côté serveur contenant du code Java • Insèrent de la logique de traitement dans des pages de présentation (HTML, WML, XML) • Concurrent aux technologies : – ASP – PHP Applications Struts 23
© Exemple de fichier JSP Présentation des JSP Applications Struts 24 • Une page JSP est écrite dans le langage cible de publication (HTML, …) • Elle contient des appels à du code Java <HTML> <HEAD> <TITLE> Exemple de page JSP </TITLE> </HEAD> <BODY> Un nombre aléatoire est : <%= Math. random() %> </BODY> </HTML>
© Fonctionnement Présentation des JSP Applications Struts 25 • Les pages JSP sont exécutées par un moteur de JSP couplé au serveur Web • Elles accèdent à du code Java qui se charge de la logique et de l'accès aux données
© Compilation des JSP Présentation des JSP • Modèle d'exécution : – Chaque page JSP est convertie en servlet – Lorsque la page JSP a déjà été compilée et exécutée une fois, la servlet reste en mémoire, elle est directement exécutée Applications Struts 26
© Format des Tags JSP Les tags JSP • L'écriture de pages JSP se base sur l'utilisation de balises (tags) prédéfinies • Il existe deux formats pour les tags JSP (Short-hand) XML Applications Struts 27 Directives Déclaration Expression Scriptlet Actions
© Expressions Les tags JSP • Permettent d’intégrer des valeurs directement dans le code HTML <%= value %> • Utilisées pour afficher une chaîne de caractères, typiquement une valeur de retour • Exemple : <P>Prix de l’article : <%= mon. Article. get. Price() %></P> Applications Struts 28 Equivalent à l’utilisation du out. println() dans la méthode service() d’une servlet
© Scriptlets Les tags JSP • Permettent d’insérer du code Java <% code java %> • Elles ont accès aux variables et aux composants déclarés dans la page • Exemple : <P> <% if (true) { %> Ce texte est affiché <% } else { %> Celui-ci n'est jamais pris en compte <% } %> </P> Applications Struts 29 Equivalent à du code simple dans la méthode service() d’une servlet
© Déclarations Les tags JSP • Utilisées pour déclarer des variables ou des méthodes dans une page <%! declaration %> • Fortement déconseillé ! • Exemple : <%! String var 1 =“x”; int count = 0; private void increment() { count++; } %> Applications Struts 30 Equivalent à une déclaration d'attribut ou d'une méthode dans la classe de la servlet
© Directives JSP Les tags JSP • Permettent de configurer la JSP <%@ directive { attribute = “value” } %> • Sont souvent placées au début du fichier • Exemples : – Inclusion statique de fichiers : <%@ include file=“headers/copyright. html” %> – Import de classes : <%@ page import=“java. util. *” %> Applications Struts 31 Équivalent à l'écriture des imports de packages et de classes au début du code de la servlet
© Directive pour les exceptions Les tags JSP Applications Struts 32 • Possibilité d’intercepter toutes les exceptions non catchées • Redirection de tous les cas d'erreur vers une page unique • Utilisation de la directive page : <%@ page is. Error. Page="false" error. Page="error. Handler. jsp" %> • Au début de la page error. Handler. jsp, il faut ajouter : <%@ page is. Error. Page="true"%>
© Liste des directives Les tags JSP Applications Struts 33 • • • <%@ page language="java" %> <%@ page extends="package. class" %> <%@ page import= "{ package. class | package. * }, . . . " %> <%@ page session="true|false" %> <%@ page buffer="none|8 kb|sizekb" %> <%@ page auto. Flush="true|false" %> <%@ page is. Thread. Safe="true|false" %> <%@ page info="text" %> <%@ page error. Page="relative. URL" %> <%@ page is. Error. Page="true|false" %> <%@ page content. Type="mime. Type [ ; charset=character. Set ]" | "text/html ; charset=ISO 8859 -1" %>
© Actions Les tags JSP • Elles effectuent une tâche prédéfinie • Aucun codage en Java n’est nécessaire • Elles se caractérisent par une balise standard XML spécifique : – use. Bean – set. Property/get. Property – include – forward Applications Struts 34
© Utilisation de Beans Les tags JSP • use. Bean : Instancie un Bean sur le serveur <jsp: use. Bean id=“notre. Bean” scope=“application” class=“com. example. Our. Bean” /> • get. Property : Récupère la propriété d’un Bean <jsp: get. Property name="notre. Bean" property="un. Attr"/> • set. Property : Met à jour la propriété d’un Bean (utilisé pour les formulaires) <jsp: set. Property name="notre. Bean" property="un. Attr" value="une. Valeur"/> <jsp: set. Property name="notre. Bean" property="un. Attr" param="un. Param"/> Applications Struts 35 <jsp: set. Property name="notre. Bean" property="*"/>
© Actions - Scope Les tags JSP Applications Struts 36 • L’action use. Bean permet de récupérer ou de créer un bean suivant une portée • 4 portées différentes : – page : objet accessible seulement dans la page où il a été créé – request : objet accessible seulement pour les pages qui sont liées à une même requête – session : objet accessible par un seul client sur toutes les pages JSP pendant la même session – application : objet accessible par tous les clients pendant toute la durée de l’application
© Utilisation d'autres ressources Les tags JSP • include : Permet d’insérer dynamiquement le contenu d'une autre ressource (servlet, JSP, HTML) <jsp: include page="shoppingcart. jsp" /> • forward : délègue le traitement de la requête à une autre ressource <jsp: forward page="shoppingcart. jsp" /> Applications Struts 37 • le send. Redirect reste possible, mais ce n'est pas une action
© Variables implicites 9 variables implicites peuvent être utilisées dans les pages JSP : Variable (scope - classe) Méthodes courantes Commentaires request get. Parameter Répresente la ( request - Sous-classe get. Parameter. Names requête HTTP de javax. servlet. get. Parameter. Values Servlet. Request ) response Applications Struts 38 (Page – Sous-classe de javax. servlet. Servlet. Response) Représente la réponse HTTP Peu utilisé dans les JSP
© Variables implicites page. Context (Page javax. servlet. jsp. Page Context) session (Session javax. servlet. http. Http. Session) application Applications Struts 39 (application javax. servlet. Servlet. Context) find. Attribute get. Attributes. Scope get. Attribute. Names. In. Scope get. Id get. Attribute put. Attribute get. Attribute. Names Représente la session utilisateur get. Mime. Type get. Real. Path Représente la Web application
© Variables implicites out (Page - javax. servlet. jsp. Jsp Writer) config (Session - javax. servlet. Servlet. Config) get. Init. Parameter, get. Init. Parameter. Names page get. Mime. Type, get. Real. Path (page - java. lang. Object) Applications Struts 40 clear, clear. Buffer, flush, Représente la get. Buffer. Size, réponse http sous get. Remaining la forme d’un flux de caractères exception (page - java. lang. Throwable) get. Message, get. Localized. Message, print. Stack. Trace Peu utilisé
© Ecrire des JSPs (1) Démarche • JSPs de présentation : – Générer dans un premier temps le code HTML de la partie présentation – Enregistrer le fichier avec l’extension. jsp – Programmer le code Java sur le serveur qui gère la partie fonctionnelle – Insérer les appels JSP pour la communication avec ce code Java Applications Struts 41 • Certaines JSPs servent uniquement à réaliser des traitements, l'écriture de la réponse est alors déléguée
© Ecrire des JSPs (2) Démarche JSP Affichage de formulaire POST JSP Traitement du formulaire forward Applications Struts 42 JSP Affichage de résultat En fonction du résultat forward JSP Affichage de page d'erreur
© Un exemple complet Démarche Ex 7 -8 Applications Struts 43 package com. example ; public class Our. Bean { private String value; public void set. Value (String s ) { value = s ; } public String get. Value ( ) { return value ; } } <HTML> Java. Bean JSP <BODY> <H 2> cette page teste notre bean </H 2> <jsp: use. Bean id= “notre. Bean” class= “com. example. Our. Bean” scope= “session” /> <% notre. Bean. set. Value(“présent”); %> <P> notre bean est <%= notre. Bean. get. Value(); %> </P> </BODY> </HTML>
Les différents modèles d’architecture technique © Les architectures distribuées Les modèles • Système centralisé – limitation très forte du nombre d’utilisateurs – pas de communication distante • Client/Serveur – 2 tiers – 3 tiers – N tiers Applications Struts 44
© Architecture 2 tiers Les architectures distribuées 2 tiers Client Unité de communication Serveur Client serveur première génération : • le client gère uniquement la couche présentation • le serveur réalise l’ensemble des applications Applications Struts 45 La couche de présentation est très succincte Les performances du serveur s’écroulent au delà de quelques utilisateurs
© Architecture 2 tiers Les architectures distribuées 2 tiers Client Unité de communication Serveur Client serveur deuxième génération : • pour utiliser la puissance des PC, les traitements applicatifs sont déportés sur ceux-ci • le serveur gère les accès à la base de données selon les requêtes des clients Applications Struts 46 Absence de standard Déploiement coûteux et difficile Trafic réseau important Difficultés d’administration
© Architecture 3 tiers (Réponses aux limitations du 2 tiers ) Les architectures distribuées 3 tiers Client Serveur Agent Unité de communication L’architecture est composée • D’un niveau client gérant la présentation • D’un niveau agent, ou serveur d'applicatif, prenant en compte les applications et les objets métiers Applications Struts 47 • D’un niveau contenant les serveurs de base de données
© Architecture 3 tiers (Réponses aux limitations 2 tiers ) Les architectures distribuées 3 tiers • Les postes clients sont pourvus • d’un navigateur Web utilisant des applets ou des contrôles Active. X – le déploiement et la mise à jour logiciel sont facilités • d’une application • L’agent à pour rôle de : Applications Struts 48 – – – fournir des services de routage de requêtes fournir des services de sécurité filtrer les requêtes fournir des services de collecte de données fournir des services de répartition de charge fournir des services transactionnels (moniteur transactionnel) – tolérance aux pannes
© Architecture 3 tiers (Réponses aux limitations 2 tiers ) Les architectures distribuées 3 tiers • Les trois niveaux sont standardisés • La logique métier se déplace sur le serveur ce qui permet un meilleur contrôle de sa diffusion • Les montées en charge sont mieux gérées puisqu’il est possible d’ajouter des machines serveurs • L’administration du système distribué est centralisée Applications Struts 49
© Architecture multi-niveaux Les architectures distribuées Logique de présentation Logique applicative Multi-niveaux Services spécifiques Services Achats Logique d’accès aux données Gestion des données Services Vente (système existant) Périphérique ERP * Applications Struts 50 * (Enterprise Resource Planning = solution de gestion intégrée).
© Architecture multi-niveaux Les architectures distribuées Multi-niveaux • L’architecture multi-niveaux est une généralisation de l’architecture 3 tiers à partir d’un modèle de composants • Les liens entre les composants sont rendus possibles par l’existence d’un bus logiciel Favorise l’intégration d’un système 3 tiers dans l’existant Permet la récriture d’un système par étapes en conservant l’existant Applications Struts 51
© Struts Applications Struts 52
© Généralités (1) Généralités • « Comment organiser les entités en charge de la gestion de l'interaction entre l'utilisateur et le système ? » • Le Framework Struts permet de réaliser une application Web basée sur – MVC 2 – JSP/Servlet (ou XML/XSLT) • Principale implémentation du MVC 2 Applications Struts 53 – Il en existe des alternatives
© Généralités (2) Généralités • Struts n’est pas destiné aux applications Web très simple – Struts introduit un niveau de complexité et de mise en route trop important. – Dès qu'une application prends de l'importance, Struts peut rapidement simplifier les choses. • Struts est distribué sous licence ASF. Applications Struts 54 – Struts peut donc être utilisé dans des applications commerciales dans le respect de ce qui est inscrit dans cette licence.
© Modèle MVC (1) Généralités Modèle MVC • MVC : Modèle – Vue – Contrôleur – Lié à l'origine des langages à objets. • Séparation en 2 couches verticales – Les objets métiers (Modèle) – Les objets IHM • Objets chargés de l'acquisition d'informations en provenance de l'utilisateur (Contrôleur) • Objets chargés de la restitution d'informations vers l'utilisateur (Vue) Applications Struts 55
© Modèle MVC (2) Généralités Modèle MVC 1 2 3 4 5 Applications Struts 56
© MVC et J 2 EE • Un contrôleur est implémenté sous forme de servlet Java. • Le modèle consiste en l'implémentation de la logique métier du site Web: – Composants Java Beans – Composants EJB (Enterprise Java Bean). • Chaque vue est implémentée via une servlet. Applications Struts 57
© Le modèle MVC II (1) Généralités Modèle MVC II • Dans MVC II : la servlet est unique : – Garantit l'unicité du point d'entrée de l'application – Prend en charge une partie du contrôle de l'application. • Les contrôleurs MVC se retrouvent alors partiellement déportés dans l'entité "dynamique de l'application" Applications Struts 58 – Assurent le contrôle de la dynamique de l'application – Gèrent les relations entre les objets métier et la présentation
© Le modèle MVC II (2) Généralités Modèle MVC II 1 2 3 7 5 6 Applications Struts 59 4
© Struts Présentation • Un contrôleur facilement configurable – Permettant d’associer des actions (méthode d’un objet Java) à des requêtes HTTP • Des librairies de tags spécifiques pour créer facilement une vue • Un Digester, permettant de parser un fichier XML et d’en récupérer facilement les information voulues • Support de l’internationalisation, gestion des sources de données (Data. Sources) … Applications Struts 60
© Fonctionnement de Struts (1) Fonctionnement Applications Struts 61
© Fonctionnement de Struts (2) Fonctionnement • Un identifiant fait office de commande et indique le traitement à exécuter • Une table de correspondance permet de faire le lien entre commande et traitement à exécuter – La commande est déterminée par une partie de l'URL transmise au servlet contrôleur, Action. Servlet Applications Struts 62
© Fonctionnement de Struts (3) Fonctionnement • Les traitements sont encapsulés dans les classes Actions. • La correspondance entre la commande et l'Action à exécuter est déclarée au sein du fichier de configuration Struts – Association URL/nom de la classe Action Applications Struts 63
© Fonctionnement de Struts (4) Fonctionnement • Automatisation des relations entre Actions et JSP par le biais des Action. Forms – Java. Beans renseignés automatiquement à partir des paramètres des requêtes transmises au servlet contrôleur – Transmises telles quelles aux Actions. Applications Struts 64
© Fonctionnement Le contrôleur Applications Struts 65 Le point d’entrée: Action. Servlet • Toutes les actions Struts passent par cette classe <!-- Action Servlet Configuration – Extrait de web. xml --> <servlet> <servlet-name>action</servlet-name> <servlet-class> org. apache. struts. action. Action. Servlet </servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config. xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*. do</url-pattern> </servlet-mapping>
© Les classes Action Fonctionnement Le contrôleur Applications Struts 66 • Héritent de la classe org. apache. struts. action. Action • Extensions du contrôleur • Permettent de traiter le modèle en réponse à une requête • Implémentent la méthode execute() : public Action. Forward execute( Action. Mapping mapping, Action. Form form, Http. Servlet. Request request, Http. Servlet. Response response)
© Mapping des actions Fonctionnement Le contrôleur • Le fichier struts-config. xml – Détermine qui traite l’action – Détermine la navigation Applications Struts 67 <action path="/search" type="fr. softeam. intranet. Search. Action" scope="request" name="search. Form" validate="true" input="/search. jsp"> <forward name="success" path="/display. Result. jsp" /> <forward name="failure" path="/login. jsp" /> </action>
© Les Action. Form Fonctionnement Les formulaires Applications Struts 68 • Classes faisant la liaison entre les vues et le contrôleur • Héritent de org. apache. struts. action. Action. Form • Possèdent des accesseurs/mutateurs sur les paramètres du formulaire • Implémentent la méthode validate() : public Action. Errors validate( Action. Mapping mapping, Http. Servlet. Request request);
© Les Dyna. Action. Form Fonctionnement Les formulaires Applications Struts 69 • Définition via le fichier de configuration • Ne nécessitent pas de classe d’implémentation • A associer au « Validator » pour les contrôles de validité
© Struts : La vue Fonctionnement La vue • La vue – La vue est constituée de pages JSP – Struts propose des librairies de tags (taglib) : Applications Struts 70 • html : pour créer du Html, des formulaires, des liens… • bean : pour accéder aux classes • logic : pour faire des tests, des boucles • tiles : pour créer des pages à base de composants réutilisables (header, footer, …) • nested : pour utiliser les autres taglib dans des contextes imbriqués
© Page 1 JSP 2 JSP 3 Web browser Fonctionnement Web container Moteur JSP Requête / session Controller Form Bean 2 Form Bean 3 struts-config. xml • mappings • • • path action [form bean] [forwards] Composant métier 2 71 SGBD Data Applications Struts Composant métier 3 Métier Composant métier 1 Présentation Form Bean 1
© Développement Applications Struts 72
© Développer le contrôle • Le développement de la couche contrôle consiste à : – Écrire une classe action pour chaque type de requête pouvant être émise par l’utilisateur – Définir dans le fichier de configuration (strutsconfig. xml) un Action. Mapping pour chaque type de requête – Mettre à jour le fichier de déploiement WEB pour qu’il intègre les composants Struts – Ajouter les composants Struts à l’application Applications Struts 73
© Les classes Action (1) Développer le contrôle Action • Le rôle d’une action: – Traiter une requête via l’exécution de sa méthode « execute » – Retourner un objet Action. Forward • « execute » effectue généralement les traitements suivants : Applications Struts 74 – Vérification de l’état courant de la session utilisateur (vérifier que l’utilisateur a été identifié) – Valider les données d’un formulaire …/…
© Les classes Action (2) Développer le contrôle Action – Traiter la requête – Mettre à jour les objets qui vont permettre de créer la page à afficher – Retourner l’objet Action. Forward qui identifie la JSP responsable de la réponse • Utilisation de la méthode find. Forward Applications Struts 75
© Action : Recommandations (1) Développer le contrôle Action • La servlet de contrôle ne crée qu’une seule instance de chaque classe Action – Même problématique la méthode service d’une servlet – Utilisation de variables locales (pas de variables d’instance) Applications Struts 76
© Action : Recommandations (2) Développer le contrôle Action • Éviter de coder de « trop » grosses classes Action – Signe du déplacement d’une partie de la logique métier dans la classe action – Problème de maintenance, perte de réutilisabilité Applications Struts 77
© Les classes Action. Mapping Développer le contrôle Action. Mapping Applications Struts 78 • Permet l’association entre une requête entrante (représentée par son URI) et la classe Action qui va la traiter • Action. Mapping – Type : Le nom complet de la classe Action qui doit traiter la requête – Name : Le nom du formulaire utilisé pour exécuter l’action – Path : URI de la requête qui permet de sélectionner l’Action. Mapping – Validate : boolean positionné à true si la méthode validate de l’Action. Form doit être appelée
© Le fichier struts-config. xml (1) Développer le contrôle Struts-config. xml Applications Struts 79
© Le fichier struts-config. xml (2) Développer le contrôle Struts-config. xml • form-beans : définition des formulaires – name : Identifiant du bean – type : Nom complet de la classe du bean • action-mappings : définition des actions – path : Chemin d’accès à l’action – type : Nom complet de la classe Action – name : Nom du <form-bean> utilisé par l’action • global-forwards : définition des associations avec les pages JSP Applications Struts 80
© Développer le contrôle Struts-config. xml Applications Struts 81 <struts-config> <form-beans> <form-bean name="logon. Form" type="org. apache. struts. example. Logon. Form"/> <form-bean name= « subscription. Form" type="org. apache. struts. action. Dyna. Action. Form> <form-property name="email" type="java. lang. String"/> </form-beans> <global-forwards type="org. apache. struts. action. Action. Forward"> <forward name="logon" path="/logon. jsp" redirect="false"/> </global-forwards> <action-mappings> <action path="/logon" type="org. apache. struts. example. Logon. Action" name="logon. Form" scope="request" input="/logon. jsp" unknown="false" validate="true"/> </action-mappings> </struts-config>
© Le fichier struts-config. xml (4) Développer le contrôle Struts-config. xml • Élément forward – Permet de devenir indépendant des nom des JSP <action path="/edit. Subscription" type="org. apache. struts. example. Edit. Subscription" name="subscription. Form" scope="request" validate="false"> <forward name="failure" path="/main. Menu. jsp"/> <forward name="success" path="/subscription. jsp"/> </action> Applications Struts 82
© Le fichier web. xml (1) Développer le contrôle Web. xml • Il s'agit d’inclure tous les composants Struts nécessaires – Exemple : Applications Struts 83 <servlet> <servlet-name>action</servlet-name> <servlet-class> org. apache. struts. action. Action. Servlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet>
© Paramètres d’initialisation (1) Développer le contrôle Web. xml Paramètres d’initialisation Applications Struts 84 • Liste des paramètres d’initialisation : – application : Nom de la classe Java contenant les ressources utilisées [NONE] – buffer. Size : Taille du buffer d’entrée [4096] – config : Chemin du fichier de configuration [/WEB-INF/strutsconfig. xml] – content : Type MIME des pages [text/html]
© Paramètres d’initialisation (2) Développer le contrôle Web. xml Paramètres d’initialisation Applications Struts 85 – debug : Niveau de détail des traces de la servlet [0] – detail : Niveau de détail des traces du Digester [0] – max. File. Size : La taille maximale d’un fichier accepté lors d’un upload de fichier [250 M] – nocache : Ajoute un header HTTP à chaque réponse pour qu’elle ne soit pas stockée sur le navigateur client [false]
© Développer le contrôle Web. xml Mapping servlet de contrôle Configurer le mapping de la servlet de contrôle • Reconnaissance par préfixe <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/execute/*</url-pattern> </servlet-mapping> – www. softeam. fr/monappli/execute/logon • Reconnaissance par suffixe <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*. do</url-pattern> </servlet-mapping> – www. softeam. fr/monappli/logon. do Applications Struts 86
© Développer le contrôle Web. xml Librairie struts Ex 9 Applications Struts 87 Configurer la librairie de balises struts • Ne configurer que les librairies réellement utilisées – Exemple : <taglib> <taglib-uri> /WEB-INF/struts-bean. tld </taglib-uri> <taglib-location> /WEB-INF/struts-bean. tld </taglib-location> </taglib> • Copier les fichiers. tld nécessaires dans le répertoire WEB-INF
© Développer la vue Applications Struts 88 • Struts définit des balises pour gérer les champs de saisie suivants : – – – – – Checkboxes Champs cachés Radios bouton Boutons de remise à zéro ( « reset» ) Listes de sélection Options Boutons « submit » Champs de saisie de texte Champs de saisie de mot de passe Zones de texte
© Développer le modèle • Développement d’un Action. Form pour chaque formulaire • La déclaration des classes Action. Form dans le fichier de configuration rend automatique les services : – Vérification de la présence d’une instance de l’Action. Form • Si elle n’existe pas, elle est créée Applications Struts 89 – Pour chaque paramètre de la requête, mise à jour de l’attribut correspondant (set. XXX) – Le Bean est ensuite passé en paramètre de la méthode execute
© Les classes Action. Form Développer le modèle • Aucun développement de méthode spécifique – Pour chaque champ de saisie un getter et setter • Utiliser la méthode validate pour vérifier que tous les champs sont bien remplis Ex 10 -12 Applications Struts 90 – Validité des informations saisies • Un formulaire n’est pas limité à une seule JSP
© Les Dyna. Action. Form (1) Développer le modèle • Struts utilisait des objets Action. Form pour stocker les valeurs des formulaires HTML – Pour chaque formulaire => une classe dérivée de Action. Form. – Lourd puisque pour chaque champ xx, il faut écrire deux méthodes set. Xx et get. Xx. • Struts nous offre la possibilité d'utiliser des formulaires dont la structure est déclarée dans le fichier struts-config. xml dans la section <form-beans> Applications Struts 91 – Créés dynamiquement par l'environnement Struts selon la structure déclarée
© Les Dyna. Action. Form (2) Développer le modèle • Dans struts-config. xml <form-beans> <form-bean name="frm. Personne" type="org. apache. struts. actions. Dyna. Action. Form"> <form-property name="nom" type="java. lang. String" initial=""/> <form-property name="age" type="java. lang. String" initial=""/> </form-bean> </form-beans> Applications Struts 92
© Développer le modèle Validation des données d’un formulaire (1) • Struts offre deux mécanismes de validations des données saisies dans les formulaires – Le plug-in Validator – La méthode validate() des Action. Forms. • Par validation, on entend deux choses : – Validation dite de « contrôle de surface » ou qualitative • Vérifier que les données saisies sont bien dans la forme attendue (ex : une donnée numérique ne contient que des chiffres) – Validation sémantique : Applications Struts 93 • Vérifier que la valeur saisie est bien celle qui est attendue par le système (ex : un numéro de carte bleue valide)
© Développer le modèle Validation des données d’un formulaire (2) • Les deux systèmes sont à même de faire les deux, mais on utilise usuellement: – Le plug-in Validator pour les controles de surface, puisqu'il ne nécéssite pas d'allerretour entre le client et le serveur – La méthode validate() des Action. Forms pour la validation sémantique Applications Struts 94
© Méthode validate() (1) Développer le modèle • Struts offre un mécanisme basique de validation des saisies utilisateurs • Pour utiliser ce mécanisme, il faut surcharger la méthode « validate » public Action. Errors validate( Action. Mapping mapping, Http. Servlet. Request request); Applications Struts 95
© Méthode validate() (2) Développer le modèle • La méthode est appelée par la servlet de contrôle après que les propriétés de l’Action. Form aient été remplies – Avant l’appel à execute de la classe Action • Validate retourne Applications Struts 96 – null si la validation est OK – Une instance de la classe Action. Errors contenant les Action. Error sinon – Les messages d'erreurs sont alors affichés grâce à la balise <html: errors/>
© Méthode validate() (3) Développer le modèle • En cas d’erreur, le contrôle est donné à l’URL spécifiée par l’attribut « input » de l’action <action path="/logon" type="org. apache. struts. example. Logon. Action" name="logon. Form" scope="request" input="/logon. jsp" validate="true"> <forward name="success" path="/main. jsp"/> </action> Ex 13 Applications Struts 97
Validation des Dyna. Action. Form (1) © Développer le modèle • Dans struts-config. xml <form-beans> <form-bean name="frm. Personne" type="com. softeam. struts. actions. Personne. Dyna. Form"> <form-property name="nom" type="java. lang. String" initial=""/> <form-property name="age" type="java. lang. String" initial=""/> </form-bean> </form-beans> Applications Struts 98
©public class Personne. Dyna. Form extends Dyna. Action. Form { public Action. Errors validate(Action. Mapping mapping, Http. Servlet. Request request) { // gestion des erreurs Action. Errors erreurs = new Action. Errors(); Développer le // le nom doit être non vide modèle String nom = (String)this. get("nom"); if (nom == null || nom. trim(). equals("")) { erreurs. add("nomvide", new Action. Error("personne. formulaire. nom. vide")); } // l'âge doit être non vide String age = (String)this. get("age"); if (age == null || age. trim(). equals("")) { erreurs. add("agevide", new Action. Error("personne. formulaire. age. vide")); } else { // l'âge doit être un entier positif if (!age. matches("^\s*\d+\s*$")) { erreurs. add("ageincorrect", new Action. Error("personne. formulaire. age. incorrect", age)); // on rend la liste des erreurs } } //if // on rend la liste d'erreurs return erreurs; } Applications Struts }//classe 99
© Utilisation avancée Applications Struts 100
© Internationalisation via Struts Internationalisation • Définition de fichiers de ressources – Un fichiers par langue – Tous les noms de fichiers de ressources devront avoir le même préfixe – Spécifié dans le fichier web. xml Applications Struts 101
© Internationalisation Définition des fichiers de ressources • Dans le répertoire classes de l’application Web – Paires de données clé/valeur – L’application référence les clés afin d'injecter les valeurs associées • Exemple – Application. Resources = fichier par défaut Applications Struts 102 Fichier "Application. Resources. properties" Caddie. Virtuel. Test. Title=Virtual Caddy Fichier "Application. Resources_fr. properties" Caddie. Virtuel. Test. Title=Caddie Virtuel
© Internationalisation Déclaration des fichiers de ressources (1) • web. xml : Paramètre application : base des noms de fichiers de ressources <servlet> <servlet-name>action</servlet-name> <servlet-class>org. apache. struts. action. Action. Servlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config. xml</param-value> </init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <param-name>application</param-name> <param-value>Application. Resources</param-value> Applications Struts </init-param> <load-on-startup>2</load-on-startup> </servlet> 103
Déclaration des fichiers de ressources (2) © • struts-config. xml : tag messageresources : base des noms de fichiers de ressources <message-resources parameter="foo. bar. My. Resource. Bundle"/> Applications Struts 104
© Utilisation des ressources Internationalisation • Utilisation du <html: html> – Paramètre locale à true <html: html locale="true"> <!-- Suite de la page --> Injection d'une valeur : <bean: message key="search. Key" /> <!-- Suite de la page --> </html: html> Applications Struts 105
© Internationalisation Changer de langue à la demande avec Struts (1) • Créer une action qui va mettre à jour la locale dans l'objet request. . <html: link href="switch. do? lang=fr&cty=FR">FR</html: link> <html: link href="switch. do? lang=en&cty=EN">EN</html: link> <html: link href="switch. do? lang=en&cty=US">US</html: link> Applications Struts 106
© Internationalisation public Action. Forward execute(Action. Mapping mapping, Action. Form form, Http. Servlet. Request request, Http. Servlet. Response response) throws java. io. IOException, javax. servlet. Servlet. Exception { //récupération des paramètres passés et de l'url du referer String country = request. get. Parameter("cty"); String language = request. get. Parameter("lang"); String source = request. get. Header( "REFERER"); Http. Session session = request. get. Session(); Action. Forward forward = null; // définition de la locale set. Locale( request, new Locale( language, country ) ); // redirection vers une page définie par défaut if( source==null ) { forward = (mapping. find. Forward("success")); } // redirection vers l'url du referrer. else { forward = new Redirecting. Action. Forward(); forward. set. Path( source ); } Applications Struts 107 return forward;
© Factoriser plusieurs actions (1) Dispatch. Action • Réaliser plusieurs actions sur un même formulaire – Par exemple, pour la gestion d'un panier virtuel, il est possible d'ajouter, de modifier ou de supprimer un élément • Dispatch. Action concentre en une seule action, l'ensemble des opérations réalisables sur une seule JSP Applications Struts 108
© Factoriser plusieurs actions (2) Dispatch. Action • On utilise un simple Java. Script qui modifie la valeur d'un champ caché lors de la soumission <SCRIPT> function set. Hidden(value){document. formulaire. hidden. value=value; } </SCRIPT> • Dans le formulaire <html: form name="formulaire"> . . . <html: hidden property="hidden" value="default"/> . . . <html: submit onclick="set. Hidden('add'); ">ADD ELEMENT</html: submit> Applications Struts </html: form> 109
© Factoriser plusieurs actions (3) Dispatch. Action • Dans l'Action concernée – Les méthodes portent les mêmes noms que les valeurs du champs hidden (à la place de la méthode execute(. . . )) public class Cart. Action extends Dispatch. Action { public Action. Forward add(Action. Mapping mapping, Action. Form form, Http. Servlet. Request request, Http. Servlet. Response response) throws IOException, Servlet. Exception {. . . } public Action. Forward remove(Action. Mapping mapping, Action. Form form, Http. Servlet. Request request, Http. Servlet. Response response) throws IOException, Servlet. Exception {. . . } public Action. Forward modify(Action. Mapping mapping, Action. Form form, Http. Servlet. Request request, Http. Servlet. Response response) Applications Struts throws IOException, Servlet. Exception {. . . } } 110
© Factoriser plusieurs actions (4) Dispatch. Action • Dans struts-config. xml – Ajouter à la déclaration de l'action l'attribut "parameter" et lui indiquer le nom du champ concerné <action path="/cart. Management" type="app. management. Cart. Action" name="cart. Form" scope="request" validate="true" parameter="hidden"/> Applications Struts 111
© Factoriser plusieurs actions (5) Lookup. Dispatch. Action • Lookup. Dispatch. Action – Si Java. Script n'est pas actif ou pas souhaité(le Dispatch. Action ne peut fonctionner) – Reprends le mécanisme du Dispatch. Action Applications Struts 112
© Factoriser plusieurs actions (6) Lookup. Dispatch. Action • Dans le struts-config. xml – Déclaration du nom du bouton de soumission qui doit être "submit". <action path="/cart. Management" type="app. management. Cart. Action" name="cart. Form" scope="request" validate="true" parameter="submit"/> Applications Struts 113
© Factoriser plusieurs actions (7) Lookup. Dispatch. Action • Dans la JSP, les boutons sont nommés grâce à une clé du Resource. Bundle <html: form. . . > <html: submit> <bean: message key="button. add"/> </html: submit> <bean: message key="button. delete"/> </html: submit> </html: form> Applications Struts 114 – Les valeurs passées sont ainsi localisées et changent donc en fonction de la locale
© Factoriser plusieurs actions (8) Lookup. Dispatch. Action • Ajouter à l'Action une méthode qui est appelée lors de la soumission – Mapping des valeurs à une méthode particulière Applications Struts 115 protected Map get. Key. Method. Map( Action. Mapping mapping, Action. Form form, Http. Servlet. Request request) { Map map = new Hash. Map(); map. put("button. add", "add"); map. put("button. delete", "delete"); return map; }
© Plug-in Plug_in • Moyen simple d’étendre Struts • Implémenter l’interface org. apache. struts. action. Plug. In – void destroy() – void init(Action. Servlet servlet, Module. Config config) Applications Struts 116 • Peut être utilisé pour l’initialisation d’une application • Ex. : Validator et Tiles sont configurés de cette façon
© Le plug-in Validator (1) Plug-in Validator • Validation avancée de formulaires – Validation coté client (Javascript) – Validation coté serveur • Seul moyen pour valider des Dyna. Action. Form • Plus complet et plus souple que la validation de base • Cet environnement vient • Livré avec Struts Applications Struts 117 – commons-validator. jar et jakarta-oro. jar
© Le plug-in Validator (2) Plug-in Validator • Pour utiliser le validator, il faut : – Que le plug-in validator soit déclaré dans le struts-config. xml – Que l'Action. Form hérite de Validator. Form – Que la page JSP intègre le tag <html: javascript>. – Qu'une règle de validation soit définie dans le fichier xml de validation Applications Struts 118
© Le plug-in Validator (3) Plug-in Validator Applications Struts 119
© Le plug-in Validator (4) Plug-in Validator • Configuration à l’aide de deux fichiers – validator-rules. xml • Définition de règles réutilisables de validation – validation. xml • Défintion de l’application des règles, par formulaire – Un certain nombre de règles pré-définies livrées avec Struts: • required, minlength, maxlength, mask, date, … Applications Struts 120
© Le plug-in Validator (5) Plug-in Validator • Dans struts-config. xml <form-beans> <form-bean name="frm. Personne" type="org. apache. struts. validator. Dyna. Validator. Form"> <form-property name="nom" type="java. lang. String" initial=""/> <form-property name="age" type="java. lang. String" initial=""/> </form-bean> </form-beans>. . . <plug-in class. Name="org. apache. struts. validator. Validator. Plug. In"> <set-property="pathnames" value="/WEB-INF/validator-rules. xml, /WEB-INF/validation. xml"/> </plug-in> Applications Struts 121
© Le plug-in Validator (6) Plug-in Validator • le validateur chargera : – validator-rules. xml est le fichier définissant les contraintes d'intégrité standard – validation. xml est le fichier définissant les contraintes d'intégrité des différents formulaires dynamiques de l'application. • Ces deux fichiers peuvent être placés n'importe où sous WEB-INF Applications Struts 122
© Le plug-in Validator (7) Plug-in Validator Applications Struts 123 • Dans validation. xml <form-validation> <global> <constant> <constant-name>entierpositif</constant-name> <constant-value>^s*d+s*$</constant-value> </constant> </global> <formset> <form name="frm. Personne"> <field property="nom" depends="required"> <arg 0 key="personne. nom"/> </field> <field property="age" depends="required, mask"> <arg 0 key="personne. age"/> <var> <var-name>mask</var-name> <var-value>${entierpositif}</var-value> </var> </field> </formset> </form-validation>
© Le plug-in Validator (8) Plug-in Validator Applications Struts 124 • <form-validation> l'ensemble des règles • <global> sert à définir des informations à portée globale, c. a. d. valable pour tous les formulaires • Une constante est définie par son nom (balise <constant-name>) et sa valeur (balise <constant-value>)
© Le plug-in Validator (9) Plug-in Validator • <formset> définit l'ensemble des formulaires pour lesquels il y a des contraintes d'intégrité à vérifier • <form name="un. Formulaire"> sert à définir les contraintes d'intégrité d'un formulaire – Ce nom doit exister dans la liste des formulaires définis dans struts-config. xml • <form> contient autant de balises <field> que de contraintes d'intégrité à vérifier pour le formulaire • <field> a les attributs suivants : – property : nom du champ du formulaire pour lequel on définit des contraintes d'intégrité – depends : liste des contraintes d'intégrité à vérifier Applications Struts 125
© Le plug-in Validator (10) Plug-in Validator Applications Struts 126 • les contraintes possibles sont les suivantes : – required (le champ doit être non vide), – mask (la valeur du champ doit correspondre à une expression régulière, définie par la variable mask), – integer : la valeur du champ doit être entier, – byte (octet), – long (entier long), – float (réel simple), – double (réel double), – short (entier court), – date (la valeur du champ doit être une date valide), – range (la valeur du champ doit être dans un intervalle donné), – email : (la valeur du champ doit être une adresse mél valide), . . .
© Upload de fichiers (1) Upload des fichiers • Formulaire HTML : doit être de type « multipart » <html: form action="/upload. do? from=sender" method="post" enctype="multipart/form-data"> <html: file property="fichier"/> . . . </html: form> Applications Struts 127
© Upload de fichiers (2) Upload des fichiers • Récupération automatique par Struts du contenu du fichier dans le form bean public class Upload. Action. Form extends Action. Form { protected Form. File file; Applications Struts 128 public Form. File get. File() { return file; } public void set. File(Form. File file) { this. file = file; } . . . }
© Datasource (1) Datasource • Pas recommandé de gérer la persistance des données dans la couche de présentation – il peut être utile d'accéder aux datasources • Tag <data-source> dans le fichier struts -config. xml Applications Struts 129
© Datasource (2) Datasource • Dans struts-config. xml <data-sources> <data-source key="First. Data. Source" type="org. apache. commons. dbcp. Basic. Data. Source"> <set-property property="driver. Class. Name" value="org. postgresql. Driver" /> <set-property property="url" value="jdbc: postgresql: //localhost/mydatabase" /> . . . </data-source> <data-source key="Second. Data. Source" type="org. apache. commons. dbcp. Basic. Data. Source"> . . . Applications Struts </data-source> </data-sources> 130
© Datasource (3) Datasource • Dans les actions. . . try { data. Source. A = get. Data. Source(request, "First. Data. Source"); my. Connection = data. Source. A. get. Connection(); . . . data. Source. B = get. Data. Source(request, "Second. Data. Source"); . . . }. . . Applications Struts 131
© Modules Applications Struts 132 • Découpage d’une application en sousmodules • Facilite le développement / la maintenance • Un fichier de configuration par module • Navigation inter-modules possible • Pas de perte de contexte (session, application, …)
© Modules (2) Modules • Déclaration des modules auprès de la servlet controleur (web. xml) <servlet> <servlet-name>action</servlet-name> <servlet-class>org. apache. struts. action. Action. Servlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config. xml</param-value> </init-param> <init-param> <param-name>config/module 1</param-name> <param-value>/WEB-INF/struts-config-module 1. xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> Applications Struts 133
© Modules (3) Modules • Navigation inter-module : attribut « context. Relative » d’une définition de « forward » <action. . . > <forward name="success" context. Relative="true" path="/module. B/index. do" redirect="true"/> </action> Applications Struts 134
© Gestion des exceptions • Possibilité de spécifier des gestionnaires globaux d’exceptions • Doivent hériter de org. apache. struts. action. Exception. Handler <global-exceptions> <exception type="java. io. IOException" handler="org. apache. struts. example. Exception. Handler"/> </global-exceptions> Applications Struts 135 • Toute exception non catchée dans une action sera traitée par le gestionnaire correspondant
© Conclusion Applications Struts 136
© Les contre Les pour et contre • Framework générique – Conçu pour répondre à tous les besoins, il offre de nombreuses fonctionnalités dont on n’a pas forcément besoin • Framework open source – Pas de support, mises à jour sporadiques Applications Struts 137
© Les pour et contre • Framework open source (Apache) – Gratuit, évolutif, adaptable • Respect de la séparation entre présentation (JSP) et contrôle du dialogue (Actions) – Excluant autant que possible code dans les JSPs Applications Struts 138 • Pool de connexions intégré • Richesse des taglibs • Flexibilité grâce à la configuration à base de fichiers XML • Internationalisation simple à mettre en oeuvre
© Alternatives à Struts Alternatives à struts • Produits commerciaux : – Barracuda • Open source : – – – Applications Struts 139 Cocoon Maverick Tapestry Web. Work Jakarta Turbine Java Server Faces • Basés sur Struts : – Expresso
- Slides: 139