Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Développer des applications WEB avec Struts
2
Plan du cours Rappels sur les composants Java pour le WEB
Servlets JSP Architecture d’un site Web Présentation de Struts Développement Utilisation avancée Conclusion
3
Les Servlets Présentation Cycle de vie Principe de fonctionnement
Échange d’informations Gestion d’une session
4
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 : CGI NSAPI / ISAPI La servlet effectue un traitement en réponse à une requête client. Sur un protocole HTTP, les servlets s'exécutent dans un serveur Web. Elles publient un résultat sur le flux de réponse HTTP. Cela peut être des pages dynamiques générées en HTML ou en XML.
5
Le principe Présentation 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 J2EE S’exécute au sein d'un moteur de servlets couplé au serveur Web Contrairement à l’applet, la servlet permet d’avoir tous les droits d’un programme Java classique puisque c’est du côté serveur qu’elle s’exécute. Il n’y a donc aucun problème de sécurité du côté client. Les packages dédiés aux servlets sont les packages javax.servlet.* Sun s’appuie désormais sur Tomcat (un projet du groupe Apache) pour fournir un moteur de servlet de référence. Auparavant, Sun s’appuyait sur le JSWDK (Java Server Web Development Kit). L'API servlet ne fait pas partie de l'environnement J2SE, donc ses classes ne sont pas dans le JDK. Il faut utiliser l'environnement J2EE.
6
Fonctionnement Client Response Web Server Request Moteur de servlets
Présentation Client Web Server Moteur de servlets Request Response Application Java Fonctionnement : La requête d’un client est envoyée vers le serveur Web (HTTP) qui la redirige vers le gestionnaire de servlets. Le gestionnaire de servlets exécute la requête. Une servlet fonctionne comme un programme java classique, c’est-à-dire qu’elle peut communiquer avec d’autres applications au niveau du serveur. Après exécution, la réponse du serveur est renvoyée au client via le serveur Web.
7
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, ... Par exemple, dans le cas de Tomcat (moteur de servlets préconisé par Sun), on peut utiliser Tomcat seul, il fonctionne en moteur de servlet et en serveur HTTP On peut coupler Tomcat avec un autre serveur HTTP (Apache par exemple) Liste non exhaustive de moteurs de servlets existants: Allaire : Apache Tomcat : BEA Weblogic : Resin : IBM Websphere : Iplanet : Oracle: Inprise : Enhydra : Orion :
8
Cycle de vie d’une servlet
Chargement et initialisation Serveur Servlet Serveur Échange de données avec les clients Client Servlet Cycle de vie : Le serveur charge la servlet et l’initialise. Il est possible de paramétrer le chargement pour qu’il ait lieu dès le démarrage du serveur ou bien à la première requête du premier utilisateur sur cette servlet. Les clients envoient des requêtes au serveur qui les transmet à la servlet. Pour chaque requête HTTP, la servlet doit fournir une réponse qui sera retournée au client. Le serveur supprime la servlet. Remarque : Dans la pratique, le chargement ne sera fait qu’une fois et le déchargement une fois: lorsque l’on décide de couper le service. Cependant, il est possible de faire plusieurs réglages: par exemple charger et décharger la servlet à chaque requête ou bien la décharger après un certain temps d’inactivité. Déchargement Serveur Servlet
9
Affectation de la requête
Conteneur de servlet Cycle de vie Conteneur de servlet Thread Servlet init() initialisation Requête HTTP Affectation de la requête service() exécution du service Cycle de vie d'une servlet : le conteneur crée une instance de la servlet à la première invocation de celle-ci. il initialise la servlet (méthode init()) lorsqu'il reçoit une requête associée à la servlet, il appelle la méthode service() avant de supprimer la servlet, il appelle la méthode destroy() l'instance est détruite, elle sera éliminée par le GC En réalité, le conteneur ne gère pas un thread par servlet mais un pool de threads. Réponse HTTP destroy() nettoyage
10
Mise en oeuvre (1) Mise en oeuvre 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(), doGet(), doPost() ... Pour qu’une classe soit une servlet, il suffit qu’elle implémente l’interface Servlet. Cependant, l’utilisation classique est l’héritage de la classe HTTPServlet qui est déjà définie dans le package javax.servlet.http. Cette classe est une implémentation de l'interface Servlet pour le protocole HTTP. Exemples de méthodes de la classe HttpServlet : La méthode doGet() correspond à la requête GET du protocole HTTP qui effectue une demande simple de documents au serveur. La méthode doPost() correspond à la requête POST du protocole HTTP qui correspond au postage d'un formulaire de saisie sur le serveur. Il existe d’autres méthodes répondant à des services HTTP comme doDelete() ou doPut().
11
Mise en oeuvre (2) Mise en oeuvre Les méthodes de type doGet() et doPost() reçoivent en paramètre deux objets : Un objet HttpServletRequest qui encapsule la requête du client (renseignée automatiquement par le moteur) Un objet HttpServletResponse qui encapsule la réponse qui sera retournée au client (à renseigner dans le code de la servlet) Les méthodes de type doGet() ou doPost() sont appelées par le serveur en fonction de la requête du client. Le corps de la méthode effectue le traitement attendu sur les données utilisateurs et renvoie la réponse. Il peut être redéfinit par l’utilisateur.
12
Ex 3 public class ExempleServlet extends HttpServlet { /**
* Réponse à une requête HTTP GET : retourne une simple page HTML */ public void doGet ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter out; String titre = "Exemple simple de document généré par une servlet"; // Renseigne la réponse sur le type du document retourné response.setContentType( "text/html" ); // Récupère un flux sur la réponse afin d’y écrire la page out = response.getWriter(); // 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("<H1>" + titre + "</H1>"); out.println("<P>Cette page provient d’une servlet."); out.println("</BODY></HTML>"); out.close(); } Mise en oeuvre Le résultat de l’appel à cette servlet par une requête HTTP affiche une page HTML simple ayant pour titre « Exemple simple de document généré par une servlet » et pour corps « Cette page provient d’une servlet ». Remarque : Écriture des liens vers la servlet. Lors de l’appel de la servlet, on va produire du HTML dans le flux de sortie (réponse). Généralement, ce HTML va contenir des liens vers cette même servlet (ex : lien retour …). On peut utiliser des informations accessible depuis la servlet pour construire dynamiquement ces liens (évite de coder des liens en dur) : Interface HttpServletRequest : getContextPath() getPathTranslated() getQueryString() getRequestURI() getServletPath() Ex 3
13
Surcharge des méthodes
Mise en oeuvre void init() GenericServlet Appelée au chargement de la servlet : initialisation, lecture des fichiers de conf… void service() Appelée à chaque invocation de la servlet void destroy() Appelée au déchargement de la servlet : destruction de tous les objets créés En fonction du type de requête du client, il est possible de surcharger également les méthodes suivantes de la classe HTTPServlet (extrait de la javadoc javax.servlet) : protected void doDelete(HttpServletRequest req, HttpServletResponse resp): Called by the server (via the service method) to allow a servlet to handle a DELETE request. protected void doGet(HttpServletRequest req, HttpServletResponse resp) : Called by the server (via the service method) to allow a servlet to handle a GET request. protected void doOptions(HttpServletRequest req, HttpServletResponse resp) : Called by the server (via the service method) to allow a servlet to handle a OPTIONS request. protected void doPost(HttpServletRequest req, HttpServletResponse resp) : Called by the server (via the service method) to allow a servlet to handle a POST request. protected void doPut(HttpServletRequest req, HttpServletResponse resp) : Called by the server (via the service method) to allow a servlet to handle a PUT request. protected void doTrace(HttpServletRequest req, HttpServletResponse resp) : Called by the server (via the service method) to allow a servlet to handle a TRACE request. protected void service(HttpServletRequest req, HttpServletResponse resp) : Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class.
14
Partage des données Servlet
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’HttpServlet dépend des autres invocations (multi-threads) => Il ne faut pas utiliser les attributs pour stocker des informations ! Exemple : public class Compteur extends HttpServlet { int compte = 0; public void service (ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); compte++; out.println("<h1>"+compte+"</h1>"); out.println("</body> </html>"); } } Si un utilisateur 1 fait une requête sur cette servlet, elle affichera 1. Si un utilisateur 2 fait une requête sur cette servlet, elle affichera 2. Si l’utilisateur 1 refait une requête sur cette servlet, elle affichera 3. En réalité, ce résultat apparaît si les appels sur la servlet sont bien séquentiels. Le problème, c'est que ces appels peuvent être effectués en parallèle dans des threads différents et le comportement de la variable compte non synchronisée peut être perturbé par ces accès multi-threads. Il est donc fortement déconseillé de faire persister des informations dans les attributs d'une servlet car cela nécessite de mettre en œuvre un mécanisme de synchronisation des appels. Ce qui remet en cause l'intérêt des servlets… Servlet Client 1 Client 2 Client 4 Client 3
15
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 : setAttribute() getAttribute()
16
La requête Echange d'informations La requête est passée en paramètre de la méthode service() (ou doGet(), doPost()…) On y récupère l'URL d’appel, les paramètres HTTP et la session utilisateur getRequestURL() getParameter(String name) getSession() 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’objet requête est un objet de la classe HttpServletRequest. La délégation de traitement est un mécanisme qui permet à une servlet de demander à une deuxième servlet de réaliser la suite du traitement et de produire le résultat. La requête existe jusqu’à ce qu’une réponse soit renvoyée au client. Elle est généralement transmise lors de la délégation du traitement (forward ou include). On peut alors l'utiliser pour y passer temporairement certaines valeurs intéressantes pour la génération de la réponse. Par exemple : public class ExempleServlet extends HttpServlet { /** Réponse à une requête HTTP GET : * retourne une simple page HTML */ public void service (HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { request.setAttribute(”monAttribut”, ”maValeur”); }
17
L’« application » Echange d'informations L’« application » est un objet de la classe ServletContext récupéré à partir de la servlet 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…) ServletContext application = this.getServletContext(); L’objet application est un objet de la classe ServletContext
18
La session La session peut être récupérée à partir de la requête
Echange d'informations La session peut être récupérée à partir de la requête 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) HttpSession session = request.getSession(); Remarque : Un gestionnaire de servlet fonctionne avec un serveur HTTP. Or le protocole HTTP ne connait pas directement la notion de session client (protocole non connecté). Pour identifier chaque session au niveau du gestionnaire de servlet, il est donc indispensable d’utiliser soit les cookies soit un identifiant de la session codé dans les urls. L'implémentation par défaut repose sur le principe des cookies. L'encodage d'URL Nécessite des modifications dans le code Java. L’objet session est un objet de la classe HttpSession. Attention à ne pas stocker des objets trop gros dans les sessions, cela peut influer sur les performances !
19
Les cookies Permettent le stockage d’informations au niveau du client
Gestion de sessions Permettent le stockage d’informations au niveau du client Utilisation de la classe javax.servlet.http.Cookie Création Récupération Les cookies sont couramment utilisés pour « pister » un client, savoir d’où il vient, quand il vient. Attention ! L’utilisateur peut interdire leur dépôt dans son navigateur. Cookie monCookie = new Cookie("nom", "valeur"); response.addCookie(monCookie); Cookie[] mesCookies = request.getCookies();
20
URL Rewriting Gestion de sessions Gestion des sessions pour des clients n’acceptant pas les cookies Méthodes HttpServletResponse.encodeURL() HttpServletResponse.encodeRedirectURL() Utilise le session ID pour retrouver la session de l’utilisateur out.println( "<tr>" "<a href=\"" response.encodeURL(monLien) "\"> + books[i].getTitle() + "</a> ); Par défaut, la gestion des sessions utilise les cookies. Pour permettre de gérer les sessions où le browser ne supporte pas ou rejette les cookies, on peut utiliser l'URL rewriting. Quand on utilise l’ URL rewriting, on appelle des méthodes qui incluent le session ID dans l’URL. Il faut appeler ces méthodes à chaque envoi de réponse de la servlet pour l’écriture de tous les liens. Soit une servlet CatalogServlet qui retourne 2 liens pour chaque livre à l’utilisateur. Ces deux liens doivent être réécrits. Quand l’utilisateur clique sur un lien réécrit, la servlet reconnaît le sessionID. Ensuite, la méthode getSession utilise ce sessionID pour récupérer l’objet HTTPSession de l’utilisateur. Si l’utilisateur clique sur un lien non-réécrit, alors la session est perdue. La servlet contactée par ce lien non–réécrit va créer une nouvelle session, mais cette nouvelle session ne contiendra pas les informations contenues dans la session perdue. Lorsqu’une session est perdue par une servlet, elle est perdue pour toutes les servlets qui la partageaient.
21
Déléguer des traitements
Gestion de sessions Possibilité de rediriger la requête HTTP sur une autre URL Possibilité de déléguer une partie de la réponse à une autre ressource : Par inclusion : include() Par délégation complète : forward() response.sendRedirect(<location>); Le sendRedirect() impose au client de reposter la requête HTTP sur une autre URL. Cette URL peut être relative à la racine du conteneur (si elle commence par "/") ou relative à l'URL de la servlet courante. L'URL passée en paramètre est exprimée sous la forme d'une chaîne de caractères. Il est dans ce cas impossible de stocker des valeurs dans la requête HTTP car l'objet qui la représente n'est pas réutilisé. L'appel à include() permet d'inclure le contenu d'une ressource, statique ou généré (servlet, JSP ou page HTML) dans la réponse. Mais la servlet d'origine conserve la main et gère la production de la réponse complète. L'appel à forward() permet de transmettre les objets de requête et de réponse à une autre ressource (servlet, JSP ou HTML) qui prend en main la gestion de la réponse. Ceci reste cependant transparent pour l'utilisateur qui ne voit que l'URL de la servlet d'entrée. Ex 4-6 ServletContext ctx = getServletContext(); RequestDispatcher rd; rd = ctx.getRequestDispatcher(<RelativeURLOfJSP>); rd.include( <RequestObject>, <ResponseObject> ); rd.forward( <RequestObject>, <ResponseObject> );
22
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
23
Présentation des JSP 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 Les JSP sont basées sur une logique de présentation. Une page JSP est une page écrite dans le langage cible (HTML, mais aussi WML, XML ou d'autres dérivés du XML) et qui intègre quelques appels à du code Java. Ce code Java est exécuté sur le serveur et le résultat des appels vient compléter la construction de la page.
24
Exemple de fichier JSP Présentation des JSP 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> Dans cet exemple, il faut remarquer l'intégration du code Java au sein de la mise en page (en HTML).
25
Fonctionnement Présentation des JSP 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 Fonctionnement : La requête d’un client est envoyée vers le serveur Web (HTTP) qui fonctionne en étroite collaboration avec le moteur de JSP. La page JSP est compilée et le code qui s’y trouve est interprété au fil de la page. La page JSP peut par exemple manipuler des beans. C’est le cas dans l’exemple présenté ci-dessus. Les objets manipulés se trouvent sur le serveur et peuvent donc dialoguer avec d’autres objets de la même manière qu’un programme java classique (ici dialogue avec une base de données). Après exécution, la réponse du serveur est renvoyée au client via le serveur Web. Parmi les moteurs de JSP les plus performants, on peut noter celui du serveur d ’application Orion ( le serveur Resin ( Tomcat est le moteur de JSP déclaré comme implémentation de référence par Sun :
26
Compilation des JSP Modèle d'exécution :
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 L'un des avantages de cette technologie est de pouvoir redéployer "à chaud" des pages JSP sur un serveur Web. Lors d'un appel à une page, le moteur de JSP vérifie la date de dernière modification de cette page, si celle-ci est plus récente que sa version compilée (la servlet qui correspond), la page JSP est alors recompilée avant d'être exécutée.
27
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 JSP (Short-hand) Directives Déclaration Expression Scriptlet XML Actions L'écriture de pages JSP repose sur l'utilisation de tags précis définis dans le standard. Le concept JSP repose également sur une API ouverte permettant de définir des tags spécifiques créés au besoin par le développeur : les tag libraries.
28
Expressions Les tags JSP Permettent d’intégrer des valeurs directement dans le code HTML Utilisées pour afficher une chaîne de caractères, typiquement une valeur de retour Exemple : <P>Prix de l’article : <%= monArticle.getPrice() %></P> <%= value %> Toute variable utilisée dans une expression est automatiquement transformée en chaîne de caractères et intégrée dans le flux HTML produit. L'équivalent de l'exemple écrit dans une servlet serait : public void service( HttpServletRequest request, HttpServletResponse) { … out.println ("<P>Prix de l'article :" + monArticle.getPrice() + "</P>"); } Le code pourrait se trouver aussi dans la méthode doGet() ou doPost() à la place de service(). Equivalent à l’utilisation du out.println() dans la méthode service() d’une servlet
29
Scriptlets Permettent d’insérer du code Java
Les tags JSP Permettent d’insérer du 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> <% code java %> L'équivalent de l'exemple écrit dans une servlet serait : public void service( HttpServletRequest request, HttpServletResponse) { … out.println ("<P>"); if (true) { out.println ("Ce texte est affiché"); } else { out.println ("Celui-ci n'est jamais pris en compte"); } out.println ("</P>"); Equivalent à du code simple dans la méthode service() d’une servlet
30
Déclarations Les tags JSP Utilisées pour déclarer des variables ou des méthodes dans une page Fortement déconseillé ! Exemple : <%! String var1 =“x”; int count = 0; private void increment() { count++; } %> <%! declaration %> La déclaration de membres au sein d'une page JSP n'est pas du tout recommandée. Ce n'est pas le but d'une page de scripts de déclarer des méthodes, elle ne doit contenir que des appels. Les déclarations éventuelles se trouvent dans une servlet, un Bean ou une classe Java. D'autre part, la déclaration d'attributs pose le même problème qu'avec les servlets : ces attributs sont partagés entre tous les threads clients, il peut y avoir des problèmes d'accès concurrents à ces données. Le code localisé dans la page JSP ne doit avoir d'intérêt que pour la présentation. L'équivalent de l'exemple écrit dans une servlet serait : public class maServlet extends HTTPServlet { String var1 = "x"; int count = 0; private void increment { count++; } … Equivalent à une déclaration d'attribut ou d'une méthode dans la classe de la servlet
31
Directives JSP Permettent de configurer la JSP
Les tags JSP Permettent de configurer la JSP 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.*” %> directive { attribute = “value” } %> L'inclusion est très pratique dans un esprit de modularité et réutilisabilité. En effet, il est ainsi possible de définir sous forme de "composants" indépendants, des pages statiques HTML, des fonctions JavaScript, ou même d'autres pages JSP et d'inclure ces composants dans une page JSP. Attention ! La directive include permet de faire de l'inclusion statique de fichiers dans un fichier composite principal. Le fichier JSP principal est compilé en une servlet avec l'intégration des éléments inclus. Ces éléments eux ne sont pas compilés en servlets. Si ces éléments sont modifiés, le serveur ne le détecte pas forcément et ne recompile donc pas la page JSP principale en servlet. L'équivalent de l'exemple d'import écrit dans une servlet serait : import java.util.* public class maServlet extends HTTPServlet { … } Équivalent à l'écriture des imports de packages et de classes au début du code de la servlet
32
Directive pour les exceptions
Les tags JSP 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 isErrorPage="false" errorPage="errorHandler.jsp" %> Au début de la page errorHandler.jsp, il faut ajouter : page isErrorPage="true"%> L’ensemble des exceptions peuvent être récupérées par une même page. Le paramètre isErrorPage permet de préciser si la page est celle utilisée pour la gestion des erreurs. Dans le cas où la page est celle qui gère les exceptions, il existe une variable prédéfinie «exception» qui permet d’avoir davantage d’informations sur l’exception qui a été levée.
33
Liste des directives <%@ page language="java" %>
page extends="package.class" %> page import= "{ package.class | package.* }, ..." %> page session="true|false" %> page buffer="none|8kb|sizekb" %> page autoFlush="true|false" %> page isThreadSafe="true|false" %> page info="text" %> page errorPage="relativeURL" %> page isErrorPage="true|false" %> page contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO " %> Les tags JSP language="java" : indique le langage utilisé dans les scriptlets. En JSP, le seul langage utilisé est Java. extends="package.class" : indique le nom complet de la classe mère Java dont hérite la classe qui sera compilée à partir de cette page JSP. import= "{ package.class | package.* }, ..." : indique la liste de packages à importer, séparés par des virgules. session="true|false" : indique si oui ou non le client doit avoir une session HTTP pour utiliser la page JSP. Crée une session si nécessaire. buffer="none|8kb|sizekb" : précise la taille du buffer (en Kb) utilisée par l’objet out pour mettre en tampon le flux de sortie envoyé par la page JSP. autoFlush="true|false" : indique si oui ou non le flux de sortie bufferisé doit être automatiquement déversé lorsque le tampon est plein. isThreadSafe="true|false" : indique si oui ou non la gestion des threads est implémentée dans la page JSP, i.e. si le moteur de JSP peut envoyer plusieurs requêtes à la même page JSP simultanément. info="text" : une chaîne de caractéres qui est incorporée dans la page JSP. errorPage="relativeURL" : path vers une page JSP d’erreur vers laquelle sont envoyées les exceptions. isErrorPage="true|false" : indique si oui ou non la page JSP est une page d’erreur. Si la valeur est « true », on peut utiliser l’objet « exception ». contentType="mimeType [ ;charset=characterSet ]" | "text/html;charset=ISO " : le type MIME et le character encoding utilisé par la page JSP pour la réponse envoyée au client.
34
Actions Elles effectuent une tâche prédéfinie
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 : useBean setProperty/getProperty include forward Les actions sont des simplifications d'écriture pour la manipulation de composants JavaBean ou pour les interactions avec d'autres pages JSP ou avec des servlets.
35
Utilisation de Beans useBean : Instancie un Bean sur le serveur
Les tags JSP useBean : Instancie un Bean sur le serveur getProperty : Récupère la propriété d’un Bean setProperty : Met à jour la propriété d’un Bean (utilisé pour les formulaires) <jsp:useBean id=“notreBean” scope=“application” class=“com.example.OurBean” /> <jsp:getProperty name="notreBean" property="unAttr"/> useBean permet de récupérer un Bean enregistré dans le scope. S'il n'existe pas, il est alors créé avec le constructeur par défaut du Bean. Dans une action setProperty le champ value peut être renseigné soit par une variable, soit par une expression JSP. Pour les formulaires, l’action <jsp:setProperty name="user" property="*"/> va appeler par introspection les accesseurs correspondant à tous les paramètres du formulaire <jsp:setProperty name="notreBean" property="unAttr" value="uneValeur"/> <jsp:setProperty name="notreBean" property="unAttr" param="unParam"/> <jsp:setProperty name="notreBean" property="*"/>
36
Actions - Scope Les tags JSP L’action useBean 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 useBean permet de récupérer un Bean enregistré dans la portée. S'il n'existe pas, il est alors créé. Le cas du scope « request » : il est utilisé dans le cas où plusieurs pages sont appelées pour une même requête, dans le cadre d’include ou de forward de pages par exemple.
37
Utilisation d'autres ressources
Les tags JSP include : Permet d’insérer dynamiquement le contenu d'une autre ressource (servlet, JSP, HTML) forward : délègue le traitement de la requête à une autre ressource le sendRedirect reste possible, mais ce n'est pas une action <jsp:include page="shoppingcart.jsp" /> L’action include permet d’inclure du code en faisant appel à une seconde JSP. Mais contrairement à la directive include, il s'agit ici d'une inclusion dynamique. Les fichiers JSP inclus ne sont que référencés par le fichier JSP principal. Ils sont eux-même compilés en servlets. En fait, la page principale inclus le résultat de l'exécution du composant inclus. Ce qui implique que lors d'une modification de l'un de ces fichiers, la recompilation est effectuée et les modifications sont bien intégrées à la page JSP principale. L’action forward, permet à la page JSP de réaliser des pré-traitements et de déléguer d'autres traitements et la production de la réponse à un deuxième composant. Une page JSP peut également implémenter une redirection comme pour les servlets. En effet, cette redirection se fait par simple appel à la méthode sendRedirect() sur l'objet response. <jsp:forward page="shoppingcart.jsp" />
38
Variables implicites 9 variables implicites peuvent être utilisées dans les pages JSP : Variables implicites Variable (scope - classe) Méthodes courantes Commentaires request ( request - Sous-classe de javax.servlet. ServletRequest ) getParameter getParameterNamesgetParameterValues Répresente la requête HTTP response (Page – Sous-classe de javax.servlet. ServletResponse) Représente la réponse HTTP Peu utilisé dans les JSP On accède directement à chacun de ces objets. Exemple : <% String maValeur = (String)request.getParameter("monParametre"); %> La référence de la réponse HTTP (response) est peu utilisée dans les JSP puisque le flux est directement géré par le serveur.
39
Variables implicites pageContext
(Page - javax.servlet.jsp.PageContext) findAttribute getAttribute getAttributesScope getAttributeNamesInScope session (Session - javax.servlet.http. HttpSession) getId getAttribute putAttribute getAttributeNames Représente la session utilisateur application (application - javax.servlet. ServletContext) getMimeType getRealPath Représente la Web application
40
Variables implicites out
(Page - javax.servlet.jsp.JspWriter) clear, clearBuffer, flush, getBufferSize, getRemaining Représente la réponse http sous la forme d’un flux de caractères config (Session - javax. servlet. ServletConfig) getInitParameter, getInitParameterNames page (page - java.lang. Object) getMimeType, getRealPath Peu utilisé exception (page - java.lang. Throwable) getMessage, getLocalizedMessage, printStackTrace Variables implicites
41
Ecrire des JSPs (1) JSPs de présentation :
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 Certaines JSPs servent uniquement à réaliser des traitements, l'écriture de la réponse est alors déléguée La ligne de conduite à suivre pour le développement de pages JSP met bien en évidence la possibilité de paralléliser le travail et d'affecter à chaque développeur la partie qui le concerne : la présentation pour le Web designer et la logique métier pour le concepteur-programmeur. Une page JSP peut parfaitement servir à effectuer des traitements comme une servlet, pour exploiter la validation d'un formulaire par exemple. En effet, elle a accès aux mêmes éléments qu'une servlet (requête, session, réponse, …).
42
Ecrire des JSPs (2) JSP Affichage de formulaire
Démarche JSP Affichage de formulaire JSP Traitement du formulaire JSP Affichage de résultat JSP Affichage de page d'erreur POST forward En fonction du résultat La définition d'un service Web se compose de plusieurs éléments : une unité de saisie, c'est un formulaire HTML généré par une page JSP, une unité de traitement de ce formulaire, c'est une page JSP qui récupère les paramètres de la requête POST, instancie les objets métiers nécessaires et réalise les traitements nécessaires, elle redirige (forward) la présentation du résultat vers une page JSP adaptée (affichage de résultat ou affichage d'erreur), une unité de réponse, c'est une page HTML générée dynamiquement en fonction du résultat du traitement ; deux pages de réponses sont programmées : une pour les cas standards et une pour les cas d'erreurs.
43
Un exemple complet JavaBean JSP Ex 7-8 package com.example ;
public class OurBean { private String value; public void setValue (String s ) { value = s ; } public String getValue ( ) { return value ; Démarche JavaBean <HTML> <BODY> <H2> cette page teste notre bean </H2> <jsp:useBean id= “notreBean” class= “com.example.OurBean” scope= “session” /> <% notreBean.setValue(“présent”); %> <P> notre bean est <%= notreBean.getValue(); %> </P> </BODY> </HTML> JSP Ex 7-8
44
Les différents modèles d’architecture technique
Les architectures distribuées Système centralisé limitation très forte du nombre d’utilisateurs pas de communication distante Client/Serveur 2 tiers 3 tiers N tiers Les modèles
45
Unité de communication
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 La couche de présentation est très succincte Les performances du serveur s’écroulent au delà de quelques utilisateurs
46
Unité de communication
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 Le déploiement et la mise à jour logiciel sont particulièrement complexes, puisque la partie applicative doit être installée sur chaque poste. Des clients peuvent alors utiliser une version applicative différente des autres. Le trafic réseau est important car chaque poste client doit envoyer des requêtes de connections et d’accès aux données. Absence de standard Déploiement coûteux et difficile Trafic réseau important Difficultés d’administration
47
Architecture 3 tiers (Réponses aux limitations du 2 tiers )
Les architectures distribuées Client Serveur Agent Unité de communication 3 tiers 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 D’un niveau contenant les serveurs de base de données
48
Architecture 3 tiers (Réponses aux limitations 2 tiers )
Les architectures distribuées Les postes clients sont pourvus d’un navigateur Web utilisant des applets ou des contrôles ActiveX le déploiement et la mise à jour logiciel sont facilités d’une application L’agent à pour rôle de : 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 3 tiers
49
Architecture 3 tiers (Réponses aux limitations 2 tiers )
Les architectures distribuées 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 3 tiers
50
Architecture multi-niveaux
Logique de présentation Logique d’accès aux données Les architectures distribuées Logique applicative Services Achats Multi-niveaux Services spécifiques Gestion des données Services Vente (système existant) Périphérique ERP * * (Enterprise Resource Planning = solution de gestion intégrée).
51
Architecture multi-niveaux
Les architectures distribuées 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 Multi-niveaux 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
52
Struts
53
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 MVC2 JSP/Servlet (ou XML/XSLT) Principale implémentation du MVC2 Il en existe des alternatives L'intérêt principal est d'obtenir une meilleur structuration de votre code. Il en découle donc une meilleur flexibilité ainsi qu'une évolutivité accrue.
54
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. Struts peut donc être utilisé dans des applications commerciales dans le respect de ce qui est inscrit dans cette licence.
55
Modèle MVC (1) MVC : Modèle – Vue – Contrôleur
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) De fait, dès le début des années 80, Smalltalk appuyait son organisation IHM sur ce modèle. Depuis lors, le modèle s'est largement répandu et est désormais connu et reconnu comme un modèle de conception (un "design pattern") mature. L'intérêt principal est d'obtenir une meilleur structuration de votre code. Il en découle donc une meilleur flexibilité ainsi qu'une évolutivité accrue. Il me semble indéniable que ce sont des caractéristiques fondamentales que nous sommes en droit d'attendre d'une application Web d'entreprise.
56
Modèle MVC (2) 1 2 3 4 5 Généralités Modèle MVC
Dans ce modèle, la dynamique applicative est de la responsabilité des trois composants. 1 – L’utilisateur manipule l’interface homme/machine. Un événement est récupéré par le contrôleur. 2 – Le contrôleur effectue l’action demandée par l’utilisateur en appelant les méthodes nécessaires sur le modèle. 3 – Le contrôleur informe la vue d’un changement d’état du modèle. 4 – La vue interroge le modèle afin de connaître son état. 5 – L’utilisateur voir le résultat de son action. Le modèle MVC fournit un support à la structuration et à l'organisation de l'Interaction Homme Machine. Il modularise la couche IHM et en réduit ainsi la complexité. Il apporte par ailleurs à cette couche IHM les propriétés de maintenabilité et de réutilisabilité que l'on est en droit d'attendre des organisations à objet bien structurées. 4 5
57
MVC et J2EE 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. Il est aussi intéressant de noter que dans une équipe de développement de site Web, on peut noter, au moins, deux types d'informaticiens. Les développeurs à proprement parlé : ils ont pour tâche l'implémentation du système. Des servlets et des (E)JB ne devrait donc pas les gêner. Mais, il y aussi les infographistes : ils sont peut-être familiarisés avec HTML ou les feuilles de styles CSS, mais du code Java peut éventuellement les rebuter. Via ce type d'architectures, chacun intervient donc sur un type de fichier qui lui est familier. Notez en complément, qu'une JSP peut être modifiée sans nécessiter de compilation (bien que l'on puisse réaliser cette étape) : pour un infographiste il est heureux qu'il en soit ainsi.
58
Le modèle MVC II (1) Dans MVC II : la servlet est unique :
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" Assurent le contrôle de la dynamique de l'application Gèrent les relations entre les objets métier et la présentation Les contrôleurs deviennent essentiellement des contrôleurs du dialogue entre l'utilisateur et les objets métiers. Il existe un grand nombre de framework basés sur une architecture MVC ou MVC 2. Citons, à titre d'exemple le framework Baraccuda, WebWork, Coccoon …
59
Le modèle MVC II (2) 1 2 3 7 4 5 6 Généralités Modèle MVC II
1 - Le client envoie une requête à l'application. La requête est prise en charge par la servlet d'entrée. 2 - La servlet d'entrée analyse la requête et réoriente celle-ci vers un contrôleur adapté. 3 - Le contrôleur sélectionné par la servlet d'entrée est responsable de l'exécution des traitements nécessaires à la satisfaction de la requête. Il sollicite les objets métiers lorsque nécessaire. 4 - Les objets métiers fournissent des données au contrôleur. 5 - Le contrôleur encapsule les données métiers dans des JavaBeans, sélectionne la JSP qui sera en charge de la construction de la réponse et lui transmet les JavaBean contenant les données métier. 6 - La JSP construit la réponse en faisant appel aux JavaBeans qui lui ont été transmis et l'envoie au navigateur. 7 - Lorsque nécessaire, pour le traitement d'erreurs essentiellement, la servlet d'entrée traite la requête directement, sélectionne la JSP de sortie et lui transmet par JavaBean les informations dont elle a besoin. 5 6
60
Struts Un contrôleur facilement configurable
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 (DataSources) … Sous la direction de Craig R Mc Clanahan qui participe également au développement de Tomcat
61
Fonctionnement de Struts (1)
62
Fonctionnement de Struts (2)
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, ActionServlet
63
Fonctionnement de Struts (3)
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
64
Fonctionnement de Struts (4)
Automatisation des relations entre Actions et JSP par le biais des ActionForms JavaBeans renseignés automatiquement à partir des paramètres des requêtes transmises au servlet contrôleur Transmises telles quelles aux Actions.
65
Le point d’entrée: ActionServlet
Fonctionnement Le contrôleur 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.ActionServlet </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> <url-pattern>*.do</url-pattern> </servlet-mapping>
66
Les classes Action Fonctionnement Le contrôleur 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 ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
67
Mapping des actions Le fichier struts-config.xml
Fonctionnement Le contrôleur Le fichier struts-config.xml Détermine qui traite l’action Détermine la navigation <action path="/search" type="fr.softeam.intranet.SearchAction" scope="request" name="searchForm" validate="true" input="/search.jsp"> <forward name="success" path="/displayResult.jsp" /> <forward name="failure" path="/login.jsp" /> </action>
68
Les ActionForm Fonctionnement Les formulaires Classes faisant la liaison entre les vues et le contrôleur Héritent de org.apache.struts.action.ActionForm Possèdent des accesseurs/mutateurs sur les paramètres du formulaire Implémentent la méthode validate() : La méthode validate permet d’automatiser la validation des formulaires côté serveur. Exemple de formulaire à une entrée: public class SearchForm extends ActionForm { /** * The value of the text the user has sent as form data */ protected String searchExpression; * Retrieve the value of the text the user has sent as * form data public String getSearchExpression() { return searchExpression; } public void setSearchExpression(String param) { searchExpression = param; public ActionErrors validate() { ActionErrors errors = new ActionErrors(); if ((searchExpression == null) || (searchExpression.equals(""))) errors.add(" searchExpression ", new ActionError("error.searchExpression.required")); return errors; public ActionErrors validate( ActionMapping mapping, HttpServletRequest request);
69
Les DynaActionForm Définition via le fichier de configuration
Fonctionnement Les formulaires 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é
70
Struts : La vue La vue La vue est constituée de pages JSP
Fonctionnement La vue La vue La vue est constituée de pages JSP Struts propose des librairies de tags (taglib) : 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
71
Présentation Métier Data SGBD Web browser Fonctionnement Web container
Page 1 JSP 1 JSP 2 JSP 3 Web browser Fonctionnement Web container Moteur JSP Requête / session Form Bean 1 Controller Présentation Form Bean 2 Form Bean 3 struts-config.xml mappings path action [form bean] [forwards] Description de la cinétique d’une application Struts : 1 - Lecture du fichier struts-config.xml au démarrage 2 - Création des mappings 3 - Requête de l’utilisateur 4 - Analyse du path pour déterminer l’action et les forwards 5 - Création / réutilisation du Form Bean associé 6 - Si soumission du formulaire, mise à jour des Form Beans à partir des paramètres de la requête 7 - Passage de contrôle à l’action concernée 8 - Récupération des données à afficher (mise à jour des beans de la requête / session) … ou sauvegarde via des règles métier 9 – Retour du forward approprié 10 - Appel de la page appropriée 11 - Traitement des taglibs : éléments de formulaire remplis à partir des beans et internalisation 12 – Envoi du résultat HTML au browser Métier Composant métier 1 Composant métier 2 Composant métier 3 Data SGBD
72
Développement
73
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 (struts-config.xml) un ActionMapping 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
74
Les classes Action (1) Le rôle d’une action:
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 ActionForward « execute » effectue généralement les traitements suivants : 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 …/…
75
Les classes Action (2) Traiter la requête
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 ActionForward qui identifie la JSP responsable de la réponse Utilisation de la méthode findForward
76
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 que la méthode service d’une servlet Utilisation de variables locales (pas de variables d’instance)
77
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é L’exemple de l’application fournie avec Struts ne respecte pas ce principe de base puisqu’elle place la logique métier dans les classes Action !
78
Les classes ActionMapping
Développer le contrôle ActionMapping Permet l’association entre une requête entrante (représentée par son URI) et la classe Action qui va la traiter ActionMapping 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’ActionMapping Validate : boolean positionné à true si la méthode validate de l’ActionForm doit être appelée
79
Le fichier struts-config.xml (1)
Développer le contrôle Struts-config.xml La section data-source spécifie les sources de données utilisées dans l’application
80
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 Chacun des forward est disponible via un appel à l’instance d’ActionMapping. Exemple : ActionMappingInstance.findForward(« logicalName »)
81
<struts-config> <form-beans>
<form-bean name="logonForm" type="org.apache.struts.example.LogonForm"/> <form-bean name=« subscriptionForm" type="org.apache.struts.action.DynaActionForm> <form-property name=" " type="java.lang.String"/> </form-bean> </form-beans> <global-forwards type="org.apache.struts.action.ActionForward"> <forward name="logon" path="/logon.jsp" redirect="false"/> </global-forwards> <action-mappings> <action path="/logon" type="org.apache.struts.example.LogonAction" name="logonForm" scope="request" input="/logon.jsp" unknown="false" validate="true"/> </action-mappings> </struts-config> Développer le contrôle Struts-config.xml L ’ActionMapping fournira le chemin /logon (en fait, l’URI de la requête dans la page JSP se terminera par /logon.do). Lorsqu’une requête associée à ce chemin est émise pour la première fois, une instance de la classe LogonAction est crée et utilisée. La servlet de contrôle centralisé recherchera ensuite un Bean associé à la clé logonForm, créant et archivant ce bean si necessaire. unknown à true signifie que cette action recevra toutes les requêtes qui n'auront pas pu être nappées avec un ActionMapping. Il ne peut y avoir qu'une seule ActionMapping avec unknown à true …
82
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="/editSubscription" type="org.apache.struts.example.EditSubscription" name="subscriptionForm" scope="request" validate="false"> <forward name="failure" path="/mainMenu.jsp"/> <forward name="success" path="/subscription.jsp"/> </action>
83
Le fichier web.xml (1) Développer le contrôle Web.xml Il s'agit d’inclure tous les composants Struts nécessaires Exemple : <servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> Struts étant basé sur un architecture MVC 2, un seul contrôleur principal se doit d'être définit. Les auteurs de Struts ont choisis d'implémenter ce contrôleur sous forme de servlet, il va donc falloir configurer cette dernière dans notre descripteur de déploiement. Le nom de la classe de contrôle de Struts est org.apache.struts.action.ActionServlet. Vous retrouverez dans ce fichier la déclaration de cette servlet qui accepte un certain nombre de paramètres, et notamment le nom du fichier du configuration de Struts (struts-config.xml).
84
Paramètres d’initialisation (1)
Développer le contrôle Web.xml Paramètres d’initialisation Liste des paramètres d’initialisation : application : Nom de la classe Java contenant les ressources utilisées [NONE] bufferSize : Taille du buffer d’entrée [4096] config : Chemin du fichier de configuration [/WEB-INF/struts-config.xml] content : Type MIME des pages [text/html] null : Toute clé de message inconnue provoque un retour null au lieu d’un message d’erreur [true] tempDir : répertoire de travail à utiliser en cas de téléchargement de fichier [Le répertoire de travail de l’application] multiPartClasse : Nom de la classe implémentant le MultiPartRequestHandler à utiliser pour traiter le téléchargement de fichier [org.apache.strutsupload.DiskMultiPartRequestHandler]
85
Paramètres d’initialisation (2)
Développer le contrôle Web.xml Paramètres d’initialisation debug : Niveau de détail des traces de la servlet [0] detail : Niveau de détail des traces du Digester [0] maxFileSize : La taille maximale d’un fichier accepté lors d’un upload de fichier [250M] nocache : Ajoute un header HTTP à chaque réponse pour qu’elle ne soit pas stockée sur le navigateur client [false] factory : nom de la classe MessageRessourceFactory utilisé pour créé l’objet MessageRessource [org.apache.struts.util.PropertyMessageRessourceFactory] formBean : Nom de la classe ActionFormBean à utiliser [org.apache.struts.action.ActionFormBean] forward : Nom de la classe ActionForward à utiliser [org.apache.struts.action.ActionForward] mapping : Nom de la classe ActionMapping à utiliser [org.apache.struts.action.ActionMapping]
86
Configurer le mapping de la servlet de contrôle
Développer le contrôle Web.xml Mapping servlet de contrôle Reconnaissance par préfixe Reconnaissance par suffixe <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/execute/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> Le mapping, à proprement parlé, est réalisé entre les URLs que les clients vont invoquer et notre contrôleur. Du coup, toute les requêtes "struts" se doivent d'être routées vers notre unique contrôleur.
87
Configurer la librairie de balises struts
Développer le contrôle Web.xml Librairie struts Ne configurer que les librairies réellement utilisées Exemple : Copier les fichiers .tld nécessaires dans le répertoire WEB-INF <taglib> <taglib-uri> /WEB-INF/struts-bean.tld </taglib-uri> <taglib-location> </taglib-location> </taglib> Le fichier de configuration doit spécifier toutes les définitions de librairies de tags qui seront utilisées par vos servlets. Struts en spécifie quatre principales. Nous reviendrons, ultérieurement dans ce cours, plus en détails sur ces librairies de tags. Ex 9
88
Développer la vue Développer la vue 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
89
Développer le modèle Développer le modèle Développement d’un ActionForm pour chaque formulaire La déclaration des classes ActionForm dans le fichier de configuration rend automatique les services : Vérification de la présence d’une instance de l’ActionForm Si elle n’existe pas, elle est créée Pour chaque paramètre de la requête, mise à jour de l’attribut correspondant (setXXX) Le Bean est ensuite passé en paramètre de la méthode execute
90
Les classes ActionForm
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 Validité des informations saisies Un formulaire n’est pas limité à une seule JSP Ex 10-12
91
Les DynaActionForm (1) Développer le modèle Struts utilisait des objets ActionForm pour stocker les valeurs des formulaires HTML Pour chaque formulaire => une classe dérivée de ActionForm. Lourd puisque pour chaque champ xx, il faut écrire deux méthodes setXx et getXx. 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> Créés dynamiquement par l'environnement Struts selon la structure déclarée
92
Les DynaActionForm (2) Dans struts-config.xml <form-beans>
Développer le modèle Dans struts-config.xml <form-beans> <form-bean name="frmPersonne" type="org.apache.struts.actions.DynaActionForm"> <form-property name="nom" type="java.lang.String" initial=""/> <form-property name="age" </form-bean> </form-beans> Pour chaque champ du formulaire on définit une balise <form-property> avec deux attributs : name : le nom du champ type : son type java L'utilisation de formulaires dynamiques facilite l'écriture des classes de type ActionForm chargées de stocker les valeurs des formulaires. On peut aller un peu plus loin dans la simplification de la gestion des formulaires.
93
Validation des données d’un formulaire (1)
Développer le modèle Struts offre deux mécanismes de validations des données saisies dans les formulaires Le plug-in Validator La méthode validate() des ActionForms. 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 : Vérifier que la valeur saisie est bien celle qui est attendue par le système (ex : un numéro de carte bleue valide)
94
Validation des données d’un formulaire (2)
Développer le modèle 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'aller-retour entre le client et le serveur La méthode validate() des ActionForms pour la validation sémantique
95
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 ActionErrors validate( ActionMapping mapping, HttpServletRequest request);
96
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’ActionForm aient été remplies Avant l’appel à execute de la classe Action Validate retourne null si la validation est OK Une instance de la classe ActionErrors contenant les ActionError sinon Les messages d'erreurs sont alors affichés grâce à la balise <html:errors/>
97
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.LogonAction" name="logonForm" scope="request" input="/logon.jsp" validate="true"> <forward name="success" path="/main.jsp"/> </action> Le paramètre validate peut recevoir les valeurs true et false. Il permet effectivement d'autoriser la validation Struts ou non. Si vous y passez la valeur false, la méthode validate ne sera donc pas invoquée. Le second paramètre, input, permet de spécifier quelle est la JSP vers laquelle rediriger en cas d'erreur dans la saisie. Ex 13
98
Validation des DynaActionForm (1)
Développer le modèle Dans struts-config.xml <form-beans> <form-bean name="frmPersonne" type="com.softeam.struts.actions.PersonneDynaForm"> <form-property name="nom" type="java.lang.String" initial=""/> <form-property name="age" </form-bean> </form-beans>
99
public class PersonneDynaForm extends DynaActionForm {
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { // gestion des erreurs ActionErrors erreurs = new ActionErrors(); // le nom doit être non vide String nom = (String)this.get("nom"); if (nom == null || nom.trim().equals("")) { erreurs.add("nomvide", new ActionError("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 ActionError("personne.formulaire.age.vide")); else { // l'âge doit être un entier positif if (!age.matches("^\\s*\\d+\\s*$")) { erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age)); // on rend la liste des erreurs } //if // on rend la liste d'erreurs return erreurs; }//classe Développer le modèle * la classe dérive de DynaActionForm * la méthode validate de la classe DynaActionForm a été réécrite. Lorsqu'elle est exécutée par le contrôleur Struts, l'objet PersonneDynaForm a été construit. Il contient un dictionnaire ayant pour clés les champs du formulaire nom et age et pour valeurs les valeurs de ces champs. Pour avoir accès à un champ au sein des méthodes de DynaActionForm on utilise la méthode Object get(String nomDuChamp). Si on veut fixer une valeur à un champ, on pourra utiliser la méthode void set(String nomDuChamp, Object valeur). On se reportera à la définition de la classe DynaActionForm pour daavantage de précisions. * une fois récupérées les valeurs des champs nom et age du formulaire, la méthode validate ne diffère pas de celle qui avait été écrite lorsque le formulaire était associé à un objet ActionForm.
100
Utilisation avancée
101
Internationalisation via Struts
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 Outre la mise en œuvre d'une architecture MVC, Struts permet aussi de prendre en charge l'internationalisation de vos applications Web. Cela signifie que vous avez à votre disposition un mécanisme simple permettant de générer un contenu adapté à la localisation de l'utilisateur. Notez aussi, à ce sujet, qu'il n'y a pas que les textes qui peuvent être amenés à changer d'une langue à une autre.
102
Définition des fichiers de ressources
Internationalisation 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 ApplicationResources = fichier par défaut Ces fichiers de ressources se doivent d'être placés dans le répertoire classes de votre application Web pour pouvoir être pris en charge par le serveur Le premier fichier est celui qui sera pris par défaut : son nom n'a pas d'information relative à la langue considérée. Par contre le second sera utilisé dans le cas ou il faudrait générer un contenu en langue française Fichier "ApplicationResources.properties" CaddieVirtuel.Test.Title=Virtual Caddy Fichier "ApplicationResources_fr.properties" CaddieVirtuel.Test.Title=Caddie Virtuel
103
Déclaration des fichiers de ressources (1)
Internationalisation web.xml : Paramètre application : base des noms de fichiers de ressources <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</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> <param-name>application</param-name> <param-value>ApplicationResources</param-value> <load-on-startup>2</load-on-startup> </servlet> Notez la présence du paramètre application qui indique la base des noms de fichiers de ressources.
104
Déclaration des fichiers de ressources (2)
struts-config.xml : tag message-resources : base des noms de fichiers de ressources <message-resources parameter="foo.bar.MyResourceBundle"/>
105
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="searchKey" /> </html:html> Le framework Struts définit plusieurs possibilités d'utilisation de ces ressources. Citons notamment l'emploie du tag <bean:message> définit dans la librairie /WEB-INF/struts-bean.tld. Ce tag injecte la valeur associée à une clé donnée : vous spécifiez la clé recherchée par l'intermédiaire de l'attribut key. Notez enfin que pour qu'une JSP supporte les mécanismes d'internationalisation, il faut le spécifier afin que les bon fichiers de ressources puisse être sélectionnés. Pour ce faire il nous faut utiliser le tag <html:html> fournit dans la librairie de tags /WEB-INF/struts-bean.tld. Ce tag accepte notamment un paramètre locale. Fixez lui la valeur true afin d'autoriser l'internationalisation.
106
Changer de langue à la demande avec Struts (1)
Internationalisation 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> La locale fait partie des attributs d'une requète http et est donc conservée durant la navigation. De plus, la JVM charge tous les bundles au démarrage. Toutes les langues définies sont donc accessibles
107
public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { //récupération des paramètres passés et de l'url du referer String country = request.getParameter("cty"); String language = request.getParameter("lang"); String source = request.getHeader( "REFERER"); HttpSession session = request.getSession(); ActionForward forward = null; // définition de la locale setLocale( request, new Locale( language, country ) ); // redirection vers une page définie par défaut if( source==null ) forward = (mapping.findForward("success")); } // redirection vers l'url du referrer. else forward = new RedirectingActionForward(); forward.setPath( source ); return forward; Internationalisation
108
Factoriser plusieurs actions (1)
DispatchAction 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 DispatchAction concentre en une seule action, l'ensemble des opérations réalisables sur une seule JSP
109
Factoriser plusieurs actions (2)
DispatchAction On utilise un simple JavaScript qui modifie la valeur d'un champ caché lors de la soumission Dans le formulaire <SCRIPT> function setHidden(value){document.formulaire.hidden.value=value;} </SCRIPT> <html:form name="formulaire"> ... <html:hidden property="hidden" value="default"/> <html:submit onclick="setHidden('add');">ADD ELEMENT</html:submit> </html:form>
110
Factoriser plusieurs actions (3)
DispatchAction 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 CartAction extends DispatchAction { public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ... } public ActionForward remove(ActionMapping mapping, ActionForm form, public ActionForward modify(ActionMapping mapping, ActionForm form, }
111
Factoriser plusieurs actions (4)
DispatchAction Dans struts-config.xml Ajouter à la déclaration de l'action l'attribut "parameter" et lui indiquer le nom du champ concerné <action path="/cartManagement" type="app.management.CartAction" name="cartForm" scope="request" validate="true" parameter="hidden"/> Il est aussi possible de créer des boutons dont les noms sont les noms des méthodes, car le nom d'un bouton est aussi la valeur renvoyée par celui-ci
112
Factoriser plusieurs actions (5)
Lookup-DispatchAction LookupDispatchAction Si JavaScript n'est pas actif ou pas souhaité(le DispatchAction ne peut fonctionner) Reprends le mécanisme du DispatchAction
113
Factoriser plusieurs actions (6)
Lookup-DispatchAction Dans le struts-config.xml Déclaration du nom du bouton de soumission qui doit être "submit". <action path="/cartManagement" type="app.management.CartAction" name="cartForm" scope="request" validate="true" parameter="submit"/>
114
Factoriser plusieurs actions (7)
Lookup-DispatchAction Dans la JSP, les boutons sont nommés grâce à une clé du ResourceBundle Les valeurs passées sont ainsi localisées et changent donc en fonction de la locale <html:form ...> <html:submit> <bean:message key="button.add"/> </html:submit> <bean:message key="button.delete"/> </html:form>
115
Factoriser plusieurs actions (8)
Lookup-DispatchAction Ajouter à l'Action une méthode qui est appelée lors de la soumission Mapping des valeurs à une méthode particulière protected Map getKeyMethodMap( ActionMapping mapping, ActionForm form, HttpServletRequest request) { Map map = new HashMap(); map.put("button.add", "add"); map.put("button.delete", "delete"); return map; }
116
Plug-in Moyen simple d’étendre Struts
Implémenter l’interface org.apache.struts.action.PlugIn void destroy() void init(ActionServlet servlet, ModuleConfig config) Peut être utilisé pour l’initialisation d’une application Ex.: Validator et Tiles sont configurés de cette façon
117
Le plug-in Validator (1)
Validation avancée de formulaires Validation coté client (Javascript) Validation coté serveur Seul moyen pour valider des DynaActionForm Plus complet et plus souple que la validation de base Cet environnement vient Livré avec Struts commons-validator.jar et jakarta-oro.jar
118
Le plug-in Validator (2)
Pour utiliser le validator, il faut : Que le plug-in validator soit déclaré dans le struts-config.xml Que l'ActionForm hérite de ValidatorForm 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
119
Le plug-in Validator (3)
120
Le plug-in Validator (4)
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, … Pour être activé, le Validator doit être déclaré dans le fichier de configuration de Struts. Le nom des fichiers de configuration du Validator ne sont pas fixés, ils peuvent être choisi librement <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/> </plug-in>
121
Le plug-in Validator (5)
Dans struts-config.xml <form-beans> <form-bean name="frmPersonne" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="nom" type="java.lang.String" initial=""/> <form-property name="age" </form-bean> </form-beans> . . . <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in> La section <plug-in> sert à charger une classe externe à Struts. Son attribut principal est classname qui indique le nom de la classe à instancier. L'objet instancié peut avoir besoin de s'initialiser. Ceci est fait au moyen de balises set-property qui a deux attributs : property : le nom de la propriété à initialiser value : la valeur de la propriété Ici, la classe DynaValidatorForm a besoin de connaître deux informations : le fichier XML qui définit les contraintes d'intégrité standard que la classe sait vérifier. le fichier XML définissant les contraintes d'intégrité des différents formulaires dynamiques de l'application Ces deux informations sont ici données par la propriété pathnames. La valeur de cette propriété est une liste de fichiers XML que le validateur chargera.
122
Le plug-in Validator (6)
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 * validator-rules.xml est le fichier définissant les contraintes d'intégrité standard. Il est livré avec Struts. On le trouvera dans <struts>\lib accompagné de son fichier DTD de définition. * validation.xml est le fichier définissant les contraintes d'intégrité des différents formulaires dynamiques de l'application. Il est construit par le développeur. Son nom est libre.
123
Le plug-in Validator (7)
Dans validation.xml <form-validation> <global> <constant> <constant-name>entierpositif</constant-name> <constant-value>^\s*\d+\s*$</constant-value> </constant> </global> <formset> <form name="frmPersonne"> <field property="nom" depends="required"> <arg0 key="personne.nom"/> </field> <field property="age" depends="required,mask"> <arg0 key="personne.age"/> <var> <var-name>mask</var-name> <var-value>${entierpositif}</var-value> </var> </form> </formset> </form-validation>
124
Le plug-in Validator (8)
<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>)
125
Le plug-in Validator (9)
<formset> définit l'ensemble des formulaires pour lesquels il y a des contraintes d'intégrité à vérifier <form name="unFormulaire"> 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
126
Le plug-in Validator (10)
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é), (la valeur du champ doit être une adresse mél valide), ... - les contraintes d'intégrité sont vérifiées dans l'ordre de l'attribut depends. Si une contrainte n'est pas vérifiée, les suivantes ne sont pas testées. - chaque contrainte est liée à un message d'erreur définie par une clé. En voici quelques-unes sous la forme contrainte (clé) : required (errors.required), mask (errors.invalid), integer (errors.integer), byte (errors.byte), long (errors.long), ... - les messages d'erreurs associés aux clés précédentes sont définies dans le fichier validator-rules.xml
127
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>
128
Upload de fichiers (2) Upload des fichiers Récupération automatique par Struts du contenu du fichier dans le form bean public class UploadActionForm extends ActionForm { protected FormFile file; public FormFile getFile() return file; } public void setFile(FormFile file) this.file = file; ...
129
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
130
Datasource (2) Dans struts-config.xml <data-sources>
<data-source key="FirstDataSource" type="org.apache.commons.dbcp.BasicDataSource"> <set-property property="driverClassName" value="org.postgresql.Driver" /> property="url" value="jdbc:postgresql://localhost/mydatabase" /> ... </data-source> <data-source key="SecondDataSource" </data-sources>
131
Datasource (3) Dans les actions ... try {
dataSourceA = getDataSource(request, "FirstDataSource"); myConnection = dataSourceA.getConnection(); dataSourceB = getDataSource(request, "SecondDataSource"); }
132
Modules Découpage d’une application en sous-modules
Facilite le développement / la maintenance Un fichier de configuration par module Navigation inter-modules possible Pas de perte de contexte (session, application, …)
133
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.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <param-name>config/module1</param-name> <param-value>/WEB-INF/struts-config-module1.xml</param-value> <load-on-startup>1</load-on-startup> </servlet>
134
Modules (3) Modules Navigation inter-module : attribut « contextRelative » d’une définition de « forward » <action ... > <forward name="success" contextRelative="true" path="/moduleB/index.do" redirect="true"/> </action>
135
Gestion des exceptions
Possibilité de spécifier des gestionnaires globaux d’exceptions Doivent hériter de org.apache.struts.action.ExceptionHandler Toute exception non catchée dans une action sera traitée par le gestionnaire correspondant <global-exceptions> <exception type="java.io.IOException" handler="org.apache.struts.example.ExceptionHandler"/> </global-exceptions>
136
Conclusion
137
Les contre Framework générique Framework open source
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
138
Les pour Framework open source (Apache)
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 Pool de connexions intégré Richesse des taglibs Flexibilité grâce à la configuration à base de fichiers XML Internationalisation simple à mettre en oeuvre
139
Alternatives à Struts Produits commerciaux : Open source :
Barracuda Open source : Cocoon Maverick Tapestry WebWork Jakarta Turbine Java Server Faces Basés sur Struts : Expresso Barracuda : Cocoon : Maverick : Tapestry : WebWork : Turbine : Expresso : JSF :
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.