Telecharger le cours
Transcription
Telecharger le cours
Développement des composants web Framework Struts 2 (Auteur : BOUZIDI Issam) Modèle MVC Le modèle MVC (Model View Controler) a été initialement développé pour le langage Smalltalk dans le but de mieux structurer une application avec une interface graphique. Ce modèle est un concept d'architecture qui propose la séparation d’une application en trois niveau : • • • le Modèle représente le comportement de l'application : traitements des données, interactions avec la base de données, etc. la Vue correspond à l'interface avec laquelle l'utilisateur interagit le Contrôleur reçoit tous les événements de l'utilisateur et enclenche les actions à effectuer et assure les échanges entre la vue et le modèle notamment grâce à des composants métiers. Modèle MVC1 Dans ce modèle, chaque requête est traitée par un contrôleur sous la forme d'une servlet. Celle-ci traite la requête, fait appel aux éléments du model si nécessaire et redirige la requête vers une JSP qui se charge de créer la réponse à l'utilisateur. L'inconvénient est donc une multiplication du nombre de servlets nécessaire à l'application. L'implémentation de plusieurs servlets nécessite beaucoup de code à produire d'autant que chaque servlet doit être déclarée dans le fichier web.xml. Client Navigateur Serveur d’application Contrôleur Servlet_1 Vue JSP Contrôleur Servlet_2 Vue JSP Base de données Traitement applicatif_1 Entités métiers (JavaBeans) Traitement applicatif_2 Entités métiers (JavaBeans) Base de données Modèle MVC2 Le principal défaut du modèle MVC est le nombre de servlets à développer pour une application. Pour simplifier les choses, le modèle MVC model 2 ou MVC2 de Sun propose de n'utiliser qu'une seule et unique servlet comme contrôleur Servlet se charge d'assurer le Worflow des traitements en fonction des requêtes http reçues. Le modèle MVC 2 est donc une évolution du modèle 1 : une unique servlet fait office de contrôleur et gère toutes les requêtes à traiter en fonction d'un paramétrage généralement sous la forme d'un fichier au format XML. Serveur d’application Client Contrôleur Servlet Navigateur Data Base Traitement applicatif Traitement applicatif Vue JSP Vue JSP Entités métiers (JavaBeans) Vue JSP Base de données Modèle MVC2 Le modèle MVC II conserve les principes du modèle MVC, mais il divise le contrôleur en deux parties en imposant un point d'entrée unique à toute l'application (première partie du contrôleur) qui déterminera à chaque requête reçue les traitements applicatifs à invoquer dynamiquement (seconde partie du contrôleur). Une application web implémentant le modèle MVC II utilise une servlet comme contrôleur traitant les requêtes. En fonction de celles-ci, elle appelle les traitements dédiés généralement encapsulés dans une classe. Modèle MVC2 Dans ce modèle, le cycle de vie d'une requête est le suivant : • • • • • Le client envoie une requête à l'application qui est prise en charge par la servlet faisant office de contrôleur. La servlet analyse la requête et appelle la classe dédiée contenant les traitements Cette classe exécute les traitements nécessaires en fonction de la requête notamment en faisant appel aux objets métiers. En fonction du résultat des traitements, la servlet redirige la requête vers la page JSP La JSP génère la réponse qui est renvoyée au client Présentation (Struts1) Struts est un Framework pour applications web développé par le projet Jakarta de la fondation Apache. C'est le plus populaire des frameworks pour le développement d'applications web avec Java. Il a été initialement développé par Craig Mc Clanahan qui l'a donné au projet Jakarta d'Apache en mai 2000. Struts met en œuvre le modèle MVC 2 basé sur une servlet faisant office de contrôleur et des JSP pour l'IHM. L'application de ce modèle permet une séparation en trois parties distinctes de l'interface, des traitements et des données de l'application. Présentation (Struts1) Correspondance entre le modèle MVC et Struts : • Vue : (pages jsp, ActionForm) • Contrôleur : (ActionServlet (struts-config.xml)) • Modèle : , Action (JavaBean, EJB). Pour le contrôleur, Struts propose une unique servlet par application qui lit la configuration de l'application dans un fichier au format XML (struts-config.xml). Cette servlet de type ActionServlet reçoit toutes les requêtes de l'utilisateur concernant l'application. En fonction du paramétrage, elle instancie un objet de type Action qui contient les traitements et renvoie une valeur particulière à la servlet. Celle ci permet de déterminer la JSP qui affichera le résultat des traitements à l'utilisateur. Les données issues de la requête sont encapsulées dans un objet de type ActionForm. Struts va utiliser l'introspection pour initialiser les champs de cet objet à partir des valeurs fournies dans la requête. Struts utilise un fichier de configuration au format XML (struts-config.xml) pour connaître le détail des éléments qu'il va gérer dans l'application et comment ils vont interagir lors des traitements. Struts-config.xml ActionServlet JSP ActionForm Action Metier Struts1 : Exemple L'exemple de cette section va simplement demander le login et le mot de passe de l'utilisateur. Et en fonction des valeurs saisies, soit l’application va afficher la page d’accueil, soit elle retournera à la page d’authentification. Cet exemple est particulièrement simple : son but est de proposer un exemple simple d'enchainement de deux pages et de récupération des données d'un formulaire. Fichier web.xml (suite) Servlet contrôleur de Struts <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> Mapping des URLs avec la servlet <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> Fichier de mapping Le fichier struts-config.xml va contenir la définition des entités utilisées dans l'exemple : l ActionForm et l'Action. Pages JSP Il faut écrire la page d'authentification. Pages JSP (suite) Il faut aussi définir la page d'accueil qui sera affichée une fois l'utilisateur authentifié. Il faut définir l'objet de type ActionForm qui va encapsuler les données saisies par l'utilisateur dans la page d'authentification. Enfin, il faut définir un objet de type Action qui va encapsuler les traitements lors de la soumission du formulaire. Présentation (Struts 2) Face aux critiques émises, les équipes de Struts et de WebWork se sont alliées pour donner naissance à WebWork 2 (fusion de Struts et WebWork) rebaptisé par la suite Struts 2 (la compatibilité ascendante Struts 1 > Struts 2 n’est pas assurée). La première version stable (2.0.6) est disponible depuis fin février 2007. L’architecture générale de struts2 est la suivante : Réponse Intercepteurs Requête Dispatcher Filter Contrôleur Model setXXX() execute() Action getXXX() View JSP Intercepteurs Requête Dispatcher Filter Erreur de conversion Création de l’action Erreur de validation Erreur de check action Réponse Forward Appel de la méthode Initialisation des variables Validation Autorisation Traçabilité Tracer une action Présentation (Struts 2) Le FilterDispatcher est le filtre de base du framework Struts 2, il permet de traiter toutes les requêtes en entrée, il permet l'accès aux éléments de base du framework pour traiter les requêtes. Intercepteurs ont pour rôle d’effectuer des pre/post traitements sur la requête (gestion des exceptions, upload de fichier, validation…). Quelques exemples d’intercepteurs personnalisés : • Check des actions des utilisateurs • Gestion de la traçabilité des actions des utilisateurs. Cycle de vie Cycle de vie standard : • • • • une fois le « dispatcher filter » passé, la requête est soumise aux intercepteurs. Ces derniers ont pour rôle d’effectuer des pre/post traitements sur la requête (gestion des exceptions, upload de fichier, validation...). l’action est instanciée, peuplée puis le formulaire est validé. invocation de la méthode contenant la logique de l’action. délégation de l’affichage à la vue. Exemple : Authentification Dans l’exemple ci après nous effectuerons une simple authentification en suivant le scénario suivant L’utilisateur au niveau de son browser va saisir son login et son mot de passe. La requête est envoyée au serveur contenant au minimum les informations suivantes : login, mot de passe, le nom de l’action qui sera exécutée. Le composant contrôleur reçoit la requête: • • • • • • Prend le nom de l’action et cherche la classe correspondante (à partir d’un fichier de configuration que nous verrons dans le cours) Instancie l’action (elle doit contenir au moins deux attributs : login, password). Affecter les paramètres reçus dans la requête (login et le mot de passe) au niveau des attributs de l’action instanciée. Exécute la méthode qui va faire le traitement (par défaut cette méthode s’appelle execute()) : Cette méthode doit par exemple chercher au niveau de la base de données et récupérer l’enregistrement utilisateur qui correspond au login et password saisis Si l’utilisateur existe, le contrôleur va envoyer le résultat à une page JSP (accueil par exemple pour afficher les attributs de l’utilisateurs (nom, prénom, adresse, …)). Sinon il va renvoyer vers une page d’erreur Return le résultat à la page JSP : Model Requête : login, password, nom_action setXXX() Contrôleur execute() Action Private login Private password Private nom Private prenom Private adresse ….. public String execute() Fichier HTML getXXX() View JSP <s:label name="nom" /> <s:label name="prenom" /> UtilisateurDAO.java UtilisateurManager.java Utilisateur.java Structure d’une application Web Fichier web.xml Le fichier /WEB-INF/web.xml est un fichier au format XML, qui est le descripteur de déploiement permettant de configurer : l'application, les servlets, les sessions, les bibliothèques de tags personnalisées, les paramètres de contexte, les pages par défaut, les ressources externes, la sécurité de l'application et des ressources J2EE. Le tag <servlet> permet de définir une servlet. Le tag <servlet-name> permet de donner un nom à la servlet qui sera utilisé pour le mapping avec l'URL par défaut de la servlet Le tag <display-name> permet de donner un nom d'affichage Le tag <description> permet de fournir une description de la servlet Le tag <servlet-class> permet de préciser le nom complètement qualifié de la classe java dont la servlet sera une instance. Le tag <init-param> permet de préciser un paramètre d'initialisation pour la servlet . Ce tag possède les tag fils <param-name>, <param-value>. Le tag <load-on-startup> permet de préciser si la servlet doit être instanciée lors de l'initialisation du conteneur Fichier web.xml (suite) Exemple : <servlet> <servlet-name>MaServlet</servlet-name> <servlet-class>test.MaServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>param1</param-name> <param-value>valeur1</param-value> </init-param> </servlet> public void init(ServletConfig config) throws ServletException { String param = config.getInitParameter("param1"); } Fichier web.xml (suite) Le tag <servlet-mapping> permet d'associer la servlet à une URL. Ce tag possède les tag fils <servlet-name> et <servlet-mapping>. Exemple : <servlet-mapping> <servlet-name>MaServlet</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> Fichier web.xml (suite) Servlet contrôleur de Struts <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> Mapping des URLs avec la servlet <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> Fichier web.xml (suite) La configuration minimale pour le bon fonctionnement d’une application struts2 est la suivante : Fichier web.xml (suite) Le tag <session-config> permet de configurer les sessions. Le tag fils <session-timeout> permet de préciser la durée maximum d'inactivité de la session avant sa destruction. La valeur fournie dans le corps de ce tag est exprimé en minutes. Exemple : <session-config> <session-timeout>15</session-timeout> </session-config> Fichier web.xml (suite) Le tag <welcome-file-list> permet de définir les pages par défaut. Chacun des fichiers est défini grâce au tag fils <welcome-file> Exemple : <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file-list> Fichier web.xml (suite) Descripteur des bibliothèques personnalisées de Struts <jsp-config> <taglib> <taglib-uri>/struts-bean</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/struts-html</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> </jsp-config> Appel dans la page JSP : Avec déclaration : <%@ taglib uri="/struts-bean" prefix="bean" %> Sans déclaration : <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> Fichier web.xml (suite) Exemple Struts 2 : Appel de la taglib dans entête de la page jsp : <%@ taglib uri="/struts-tags" prefix="s"%> Appel dans le corps de la page jsp : <s:textfield label="User Name" name="login" /> Structure d'un fichier .war Structure d'un fichier .war (suite) Le nom du fichier .war est important car ce nom sera automatiquement associé dans l'url pour l'accès à l'application en concaténant le nom du domaine, un slash et le nom du fichier war. Exemple : pour un serveur web sur le poste local avec un fichier test.war déployé sur le serveur d'application, l'url pour accéder à l'application web sera http://localhost/test/ Le répertoire WEB-INF et le fichier web.xml qu'il contient doivent obligatoirement être présents dans l'archive. Le fichier web.xml est le descripteur de déploiement de l'application web. Le répertoire WEB-INF/classes est automatiquement ajouté par le conteneur au CLASSPATH lors du déploiement de l'application web. Fichier struts.xml Le fichier struts.xml permet de configurer le mapping entre l'URL et l'implémentation de l'action. C’est ce fichier qui permet de définir le workflow de navigation de toute l’application. Dans la configuration par défaut d’une application qui utilise le framework struts2, il est préférable de placer ce fichier dans le dossier src (dossier racine de votre application web). La balise racine est <struts>. Toutes les autres balises seront contenue dans cette dernière. Le fichier struts.xml peut contenir les balises suivantes: include, package, …. Tag include C’est un tag fils du tag struts Ce tag permet de structurer l’application en incluant d’autres fichiers de configuration. Ce tag permet notamment de séparer l’application à plusieurs modules, et créer pour chaque module un fichier de mapping. Exemple : • • • Module d’administration Module de gestion des utilisateurs Module de gestion des commandes Le fichier de configuration à inclure, doit avoir la même structure que le fichier struts.xml Le Tag include contient une seule option « file » qui permet d’indiquer le nom du fichier à inclure. Tag include <struts> <include file="admin-config.xml" /> <include file=« utilisateur-config.xml" /> <include file=« commande-config.xml" /> </struts> Pour inclure ces fichiers, l’ordre est très important. Les informations dans le fichier inclus seront disponibles à partir de l’endroit ou le tag a été inclus. Donc pour utiliser un tag qui est configuré dans un autre fichier, il faut que ce dernier soit référencé avant son utilisation. Comme nous avons des fichiers de configuration que pouvons inclure d’une manière explicite, d’autres fichiers sont inclus d’une manière automatique. Par exemple : • • Struts-default.xml Struts-plugin.xml Ces deux fichiers contiennent les configurations par défaut qui sont hérités depuis l’API struts2 (intercepteur, validateur, gestion des exceptions, …). Tag package Ce tag permet de fragmenter la configuration de l'application en package. On peut par exemple créer un package pour chaque module de l'application ou par un ensemble de fonctionnalités communes. La syntaxe est la suivante : <package name=”test” namespace=”/tests” extends=”struts-default” abstract=”false” > …….. </package> Tag package name: nom du package, il doit être unique. namespace: indique le chemin depuis lequel les actions vont être accessible. Autrement dit, c’est le mapping entre l’url et le package. • Exemple: si nous avons deux packages avec deux namespace différents « package1 » et « package2 » les URLs correspondantes doivent être écrites sous le format suivant : • /myApplication/package1/my.action • /myApplication/package2/my.action extends: un package peut étendre un autre package, ce qui permet d'accéder à toutes les propriétés du package parent. abstract: si le package est abstract (valeur=true) il ne peut pas être accédé à partir d'une URL, il est juste utilisé pour l'organisation de la configuration. Il est recommandé d'étendre le package par défaut struts-default pour ne pas être obligé à redéfinir des intercepteurs nécessaire pour le fonctionnement de Struts 2. Ce package est contenu, bien sur, dans le fichier de configuration « strutsdefault.xml ». Tag Action La concept d’action est fondamental dans la plupart des frameworks destinés pour le développement d’application web. Dans struts2 en général une action correspond à une méthode à exécuter dans une classe. La requête envoyée par le client est mappée à une action, afin d’exécuter le traitement demandé (ou le déléguer à la couche métier). <action name="profil" method="getProfil" class="pl.AuthentificationVA"> <result name="success" >profil.jsp</result> </action> Tag Action name : fourni le nom de l’action qui sera contenu dans l’url envoyée par le client. Dans l’exemple précédent l’url aura la syntaxe suivante : « …./profil.action » calss : la classe qui contient la méthode à exécuter. method : le nom de la méthode à exécuter dans la classe mentionnée. • • Si cette option n’est pas mentionnée dans la balise action, le framework appelle par défaut la méthode execute() de la classe. Exemple : <action name="connection" class="pl.AuthentificationVA" > <result name="success" >accueil.jsp</result> <result name="error" >connect.jsp</result> </action> Tag Action (URL) Prenant l’exemple ci après : <package name="pl" namespace="/gestProfil" extends="struts-default"> <action name="profil" method="getProfil" class="pl.AuthentificationVA"> <result name="success" >profil.jsp</result> </action> </package> L’URL envoyée par client doit respecter la syntaxe suivante : • http://serveur:port/conxteApp/package/nomAction Exemple : • http://serveur:port/admin/gestionProfil/profil.action Action (Bean) Contrairement à Struts 1.x, la classe (action) qui contient les méthodes (actions) à exécuter n’a pas besoin d’étendre aucune classe ni implémenter aucune interface. Cette classe : • • est simplement un POJO (Bean), qui contient des attributs et des méthodes. a une méthode qui s’appelle execute(). exécutée par défaut. Les méthodes qui sont appelées au niveau du fichier de configuration doivent retourner un String. Le contrôleur se base sur la valeur de retour de la méthode pour rediriger la réponse vers une page jsp. Action (Bean) : méthode par défaut Exemple 1 : Implémentation de la méthode execute() public class AuthentificationVA { String login; String password; String nom; String prenom; public String execute() { if (getLogin().equals("56480") && getPassword().equals("test")) { setNom("BOUZIDI"); setPrenom("Issam"); return "success"; } else return "error"; } Action (Bean) : méthode par défaut Exemple du fichier struts.xml correspondant : <struts> <package name="pl" namespace="/" extends="struts-default"> <action name="connection" class="pl.AuthentificationVA"> <result name="success" >accueil.jsp</result> <result name="error" >connect.jsp</result> </action> </package> </struts> URL correspondante : http://localhost:8080/myAppli/connection.action Action (Bean) : méthode personnalisée Exemple 2 : Implémentation de la méthode qui permet d’ajouter une commande : public class CommandeVA { String code; String libelle; String montant; public String ajouterCommande() { try { modele.Commande commande = new modele.Commande(); commande.setCode(getCode()); commande.setLibelle(getLibelle()); commande.setMontant(getMontant()); CommandeDAO.ajouterCommande(commande); return "success"; } catch (Exception e) { return "error"; }} Action (Bean) : méthode personnalisée Exemple du fichier struts.xml correspondant : <struts> <package name="pl" namespace="/" extends="struts-default"> <action name="ajoutCommande" method="ajouterCommande" class="pl.CommandeVA"> <result name="success" >listeCommandes.jsp</result> <result name="error" >pageErreur.jsp</result> </action> </package> </struts> URL correspondante : http://localhost:8080/myAppli/ajoutCommande.action Action (Bean) : méthode personnalisée Pour structurer notre fichier de mapping, struts.xml, nous pouvons déclarer un package qui ne contient que les actions correspondant à la gestion des commandes. <package name="pl" namespace="/gestCommandes" extends="struts-default"> <action name="ajoutCommande" method="ajouterCommande" class="pl.CommandeVA"> <result name="success" >listeCommandes.jsp</result> <result name="error" >pageErreur.jsp</result> </action> </package> URL correspondante : http://localhost:8080/myAppli/gestCommandes/ajoutCommande.action Tags Struts2 Pour utiliser les tags du framework struts2, il faut tout d’abord insérer la bibliothèque correspondante dans la page jsp, utilisant la syntaxe suivante : <%@ taglib uri="/struts-tags" prefix="s"%> La bibliothèque est incluse dans le fichier jar du framework. Tags Struts2 (suite) Exemple de tags : <s:form action="connection" > <s:textfield label="User Name" name="login" /> <s:password label="Password" name="password" /> <s:submit label="Valider"/> </s:form> <H1>Bonjour <s:label name="nom" /> <s:label name="prenom" /> </H1> Tags Struts2 (suite) Autres exemples : Tag radio <s:radio name="sexe" list="sexValues" listKey="code" listValue="libelle"/> public Collection getSexValues() { Collection values = new Vector(); Value value1 = new Value(); Value value2 = new Value(); value1.setCode("masculin"); value1.setLibelle("Masculin"); value2.setCode("feminin"); value2.setLibelle("Feminin"); values.add(value1); values.add(value2); return values; } Tags Struts2 (suite) Autres exemples : Tag select <s:select name="fonction" list="allFonctions" listKey="code" listValue="libelle"/> public Collection getAllFonctions() { Collection fonctions = new Vector(); Value value1 = new Value(); Value value2 = new Value(); value1.setCode("enseignant"); value1.setLibelle("Enseignant"); value2.setCode("etudiant"); value2.setLibelle("Etudiant"); fonctions.add(value1); fonctions.add(value2); return fonctions; } Présentation des JSP Les JSP sont basées sur les servlets 1. 2. 3. Au premier appel de la page JSP, le moteur de JSP génère et compile automatiquement une servlet qui permet la génération de la page web. Le code HTML est repris intégralement dans la servlet. Le code Java est inséré dans la servlet. La servlet générée est compilée et sauvegardée puis elle est exécutée. Les appels suivants de la JSP sont beaucoup plus rapides car la servlet, conservée par le serveur, est directement exécutée Les Tags JSP Il existe trois types de tags : • tags de directives : ils permettent de • • contrôler la structure de la servlet générée. tags de scripting: ils permettent d'insérer du code Java dans la servlet. tags d'actions: ils facilitent l'utilisation de composants. Attention : Les noms des tags sont sensibles à la casse Les tags de directives <%@ ... %> Les directives permettent de préciser des informations globales sur la page JSP. Les spécifications des JSP définissent trois directives. • • • page : permet de définir des options de configuration include : permet d'inclure des fichiers statiques dans la JSP avant la génération de la servlet taglib : permet de définir des tags personnalisés Leur syntaxe est la suivante : <%@ directive attribut="valeur" ... %> La directive « page » Cette directive doit être utilisée dans toutes les pages JSP : elle permet de définir des options qui s'appliquent à toute la JSP. Elle peut être placée n'importe ou dans le source mais il est préférable de la mettre en début de fichier, avant même le tag <HTML>. Les options définies par cette directive sont de la forme option=valeur. Exemple : • • • <%@ page import="java.util.*" %> <%@ page import="java.util.Vector" %> <%@ page info="Ma premiere JSP"%> La directive « page » (suite) import= "{ package.class | package.* }" Cette option permet d'importer des classes contenues dans des packages utilisées dans le code de la JSP. extends="package.class" Cette option permet de préciser la classe qui sera la super classe de l'objet Java créé à partir de la JSP. info="text" Cette option permet de préciser un petit descriptif de la JSP. Le texte fourni sera renvoyé par la méthode getServletInfo() de la servlet générée. session="true|false" Préciser si la page peut accéder aux données mise en session ou pas. La valeur par défaut (true) permet l'utilisation d'un objet session de type HttpSession qui permet de gérer des informations dans une session. La directive « include » Cette directive permet d'inclure un fichier dans le source JSP. Le fichier inclus peut être un fragment de code JSP, HTML ou Java. Le fichier est inclus dans la JSP avant que celle ci ne soit interprétée par le moteur de JSP. Ce tag est particulièrement utile pour insérer un élément commun à plusieurs pages tel qu'un en-tête ou un bas de page. Si le fichier inclus est un fichier HTML, celui ci ne doit pas contenir de tag <HTML>, </HTML>, <BODY> ou </BODY> qui ferait double emploi avec ceux présents dans le fichier JSP La syntaxe est la suivante : <%@ include file="chemin relatif du fichier" %> La directive « include » (suite) Exemple : <HTML> <HEAD> <TITLE>Essai de page JSP</TITLE> </HEAD> <BODY> <p align="center"> Test d'inclusion d'un fichier dans la JSP </p> <%@ include file="bonjour.htm"%> <p align="center">fin</p> </BODY> </HTML> Les tags de scripting Ces tags permettent d'insérer du code Java qui sera inclus dans la servlet générée à partir de la JSP. Il existe trois tags pour insérer du code Java : • • • le tag de déclaration : le code Java est inclus dans le corps de la servlet générée. Ce code peut être la déclaration de variables d'instances ou de classes ou la déclaration de méthodes. le tag d'expression : évalue une expression et insère le résultat sous forme de chaîne de caractères dans la page web générée. le tag de scriptlets : par défaut, le code Java est inclus dans la méthode service() de la servlet. Le tag de déclaration <%! ... %> Ce tag permet de déclarer des variables ou des méthodes qui pourront être utilisées dans la JSP. La syntaxe est la suivante : <%! déclarations %> Exemple : <%! int i = 0; %> <%! dateDuJour = new java.util.Date(); %> Le tag d'expressions <%= ... %> Le moteur de JSP remplace ce tag par le résultat de l'évaluation de l'expression présente dans le tag. Ce résultat est toujours converti en une chaîne Ce tag est un raccourci pour éviter de faire appel à la méthode println() lors de l'insertion de données dynamiques dans le fichier HTML La syntaxe est la suivante : <%= expression %> Le signe '=' doit être collé au signe '%'. Le tag d'expressions <%= ... %> (suite) Exemple : <%@ page import="java.util.*" %> <HTML> <HEAD> <TITLE>Essai de page JSP</TITLE> </HEAD> <BODY> <p align="center">Date du jour : <%= new Date() %> </p> </BODY> </HTML> Le tag des scriptlets <% ... %> Ce tag contient du code Java nommé un scriptlet. La syntaxe est la suivante : <% code Java %> Exemple <%@ page import="java.util.Date"%> <html> <body> <%! Date dateDuJour; %> <% dateDuJour = new Date();%> Date du jour : <%= dateDuJour %><BR> </body> </html> Le tag des scriptlets <% ... %> (suite) Par défaut, le code inclus dans le tag est inséré dans la méthode service() de la servlet générée à partir de la JSP. Ce tag ne peut pas contenir autre chose que du code Java : il ne peut pas par exemple contenir de tags HTML ou JSP Pour faire cela, il faut fermer le tag du scriptlet, mettre le tag HTML ou JSP puis de nouveau commencer un tag de scriptlet pour continuer le code Le tag des scriptlets <% ... %> (suite) Exemple : <HTML> <HEAD> <TITLE>Essai de page JSP</TITLE> </HEAD> <BODY> <% for (int i=0; i<10; i++) { %> <%= i %> <br> <% }%> </BODY> </HTML> Les tags de commentaires Il existe deux types de commentaires avec les JSP : • les commentaires visibles dans le code HTML • les commentaires invisibles dans le code HTML Les commentaires HTML <!-- ... --> Ces commentaires sont ceux définis par format HTML. Ils sont intégralement reconduits dans le fichier HTML généré. Il est possible d'insérer, dans ce tag, un tag JSP de type expression qui sera exécuté. La syntaxe est la suivante : <!-- commentaires [ <%= expression %> ] --> Exemple : <%@ page import="java.util.*" %> <BODY> <!-- Cette page a été générée le <%= new Date() %> --> <p>Bonjour</p> </BODY> Les commentaires cachés <%-- ... --%> Les commentaires cachés sont utilisés pour documenter la page JSP. Leur contenu est ignoré par le moteur de JSP et ne sont donc pas reconduits dans la page HTML générée. La syntaxe est la suivante : <%-- commentaires --%> Exemple : <BODY> <%-- Commentaires de la page JSP --%> <p>Bonjour</p> </BODY> Les bibliothèques de tag personnalisées Les bibliothèques de tags (taglibs) ou tags personnalisés (custom tags) permettent de définir ses propres tags basés sur XML, de les regrouper dans une bibliothèque et de les réutiliser dans des JSP. C'est une extension de la technologie JSP apparue à partir de la version 1.1 des spécifications. Un tag personnalisé : est un élément du langage JSP défini par un développeur pour des besoins particuliers qui ne sont pas traités en standard par les JSP. Elles permettent de définir ses propres tags qui réaliseront des actions pour générer la réponse. Le principal but est de favoriser la séparation des rôles entre le développeur Java et concepteur de page web. Les bibliothèques de tag personnalisées (suite) Les tags personnalisés sont adaptés pour enlever du code Java inclus dans les JSP et le déporter dans une classe dédiée. Cette classe est physiquement un javabean qui implémente une interface particulière. La principale différence entre un javabean et un tag personnalisé est que ce dernier tient compte de l'environnement dans lequel il s'exécute (notamment la JSP et le contexte de l'application web ) et interagit avec lui. Les bibliothèques de tag personnalisées (suite) Les avantages des bibliothèques de tags personnalisés sont : • un suppression du code Java dans la JSP remplacé par un tag XML facilement compréhensible ce qui simplifie grandement la JSP • une API facile à mettre en ouvre • une forte et facile réutilisabilité des tags développés • une maintenance des JSP facilitée La définition d'une bibliothèque de tags comprend plusieurs entités : • une classe dit "handler" pour chaque tag qui compose la bibliothèque • un fichier de description de la bibliothèque Bibliothèques de tag Handler de tag Chaque tag est associé à une classe qui va contenir les traitements à exécuter lors de l'utilisation du tag. Une telle classe est nommée "handler de tag" (ou tag handler). Pour permettre leur appel, une telle classe doit obligatoirement implémenter directement ou indirectement l'interface javax.servlet.jsp.tagext.Tag Pour plus de facilité, l'API JSP propose la classe TagSupport qui implémente l'interface Tag. Cette classe, contenue dans le package javax.servlet.jsp.tagext, propose des implémentations par défaut des méthodes de l'interface. Pour définir un handler de tag, il suffit d'hériter de la classe TagSupport . Bibliothèques de tag Handler de tag (suite) Les princpales méthodes de l’inteface Tag • • int doStartTag() : Traitements à la rencontre du tag de début int doEndTag() : Traitements à la rencontre du tag de fin La méthode doStartTag() est appelée lors de la rencontre du tag d'ouverture et contient les traitements à effectuer dans ce cas. Elle doit renvoyer un entier prédéfini qui indique comment va se poursuivre le traitement du tag : • • EVAL_BODY_INCLUDE : poursuite du traitement avec évaluation du corps du tag SKIP_BODY : poursuite du traitement sans évaluation du corps du tag Bibliothèques de tag Handler de tag (suite) La méthode doEndTag() est appelée lors de la rencontre du tag de fermeture et contient les traitements à effectuer dans ce cas. Elle doit renvoyer un entier prédéfini qui indique comment va se poursuivre le traitement de la JSP. • • EVAL_PAGE : poursuite du traitement de la JSP SKIP_PAGE : ne pas poursuivre le traitement du reste de la JSP Un handler de tag possède un objet qui permet d'avoir un accès aux objets implicites de la JSP. Cet objet est du type javax.servlet.jsp.PageContext Bibliothèques de tag Handler de tag (suite) Le cycle de vie général d'un tag est le suivant : • lors de la rencontre du début du tag, un objet du type du handler est instancié • plusieurs propriétés sont initialisées (pageContext, parent, ...) en utilisant les setters correspondant • si le tag contient des attributs, les setters correspondant sont appelés pour alimenter leur valeur • la méthode doStartTag() est appelée • si la méthode doStartTag() renvoie la valeur EVAL_BODYINCLUDE alors le contenu du corps du tag est évalué • lors de la rencontre de la fin du tag, appel de la méthode doEndTag() • si la méthode doEndTag() renvoie la valeur EVAL_PAGE alors l'évaluation de la page se poursuit, si elle renvoie la valeur SKIP_PAGE elle ne se poursuit pas Bibliothèques de tag Handler de tag (suite) public class TagMenu extends TagSupport { public int doStartTag() throws JspException { int out = SKIP_BODY; try { String menu1 ="<a href=\"authentification.html\">Page d'authentification </a>"; String menu2 ="<a href=\"testjsp1.jsp\">Page de consulation</a>"; pageContext.getOut().print(menu1); pageContext.getOut().print("<br>"); pageContext.getOut().print(menu2); } catch (Exception ex) { ex.getMessage(); } return out; } } Les paramètres d'un tag Un tag peut avoir un ou plusieurs paramètres qui seront transmis à la classe via des attributs Pour chacun des paramètres, il faut définir des getter et des setter en respectant les règles et conventions des Java beans. Il est impératif de définir un champ, un setter et éventuellement un accesseur pour chaque attribut. La JSP utilisera le setter pour fournir à l'objet (le handler) la valeur de l'attribut. Fichier de description de la bibliothèque de tags (TLD) Le fichier de description de la bibliothèque de tags (tag library descriptor file) est un fichier au format XML qui décrit une bibliothèque de tag. Les informations qu'il contient concerne la bibliothèque de tags elle même et concerne aussi chacun des tags qui la compose. Ce fichier doit toujours avoir pour extension .tld Il doit être placé dans le répertoire web-inf du fichier war ou dans un de ces sous répertoires. Le plus pratique est de tous les regrouper dans un répertoire nommé par exemple tags ou tld. Fichier de description de la bibliothèque de tags (TLD) (suite) Exemple : <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>testtaglib</shortname> <uri>http://perso.jmd.test.taglib</uri> <info>Bibliotheque de test des taglibs</info> <tag> <name>tagPrintUser</name> <tagclass>package.TagPrintUser</tagclass> <info>Tag qui affiche les informations de l’utilisateur</info> </tag> </taglib> Fichier de description de la bibliothèque de tags (TLD) (suite) Exemple avec des attributs : <tag> <name>checkAction</name> <tag-class>package.CheckAction</tag-class> <description>Tag qui permet d’afficher ou non une action à un utilisateur </description> <attribute> <name>code</name> <required>true</required> <type>int</type> <description>le code d’une action</description> </attribute> </tag> Fichier de description de la bibliothèque de tags (TLD) (suite) Pour chaque bibliothèque à utiliser dans une JSP, il faut la déclarer en utilisant la directive taglib avant son utilisation. Le plus simple est d'effectuer ces déclarations tout au début du code de la JSP. Cette directive possède deux attributs : • • uri : chemin de la bibliothèque prefix : un préfix qui servira d'espace de noms pour les tags de la bibliothèque dans la JSP Exemple <%@ taglib uri="/WEB-INF/tld/testtaglib.tld" prefix="maTagLib" %> Fichier de description de la bibliothèque de tags (TLD) (suite) L'appel d'un tag dans une page jsp se fait en utilisant un tag dont le nom à la forme suivante : • • <prefix:tag> ou <prefix:tag> ... </prefix:tag> Le préfix est celui défini dans la directive taglib. Exemple : • <maTagLib:testtaglib1/> Fichier de description de la bibliothèque de tags (TLD) (suite) Le tag peut avoir des attributs si ceux ci ont été définis. La syntaxe pour les utiliser respecte la norme XML : • <prefix:tag attribut="valeur"/> Validation Struts Struts définit un Framework de validation des données qui permet de contrôler la forme syntaxique des attributs tout en appliquant des règles de gestion. Exemple de types de validation : • Validation du type de données : chaine de caractère, entier, réel, date, … • Validation des règles de saisies : chaine obligatoires ou non. • Validation des règles de gestion : une valeur doit entre comprise en deux valeurs, une valeur qui doit respecter une expression régulière, … La validation des données se fait coté serveur. Validation Struts (suite) Pour utiliser la validation struts on doit suivre les étapes suivantes : • • • • • Notre action doit étendre la classe com.opensymphony.xwork2.ActionSupport. Créer un fichier de validation au format xml qui permet de configurer les règles de validation des attributs le nom du fichier doit respecter la nomenclature suivante : • • NomAction-validation.xml ou NomAction-alias-validation.xml Le fichier de validation xml doit être mis dans le même package que l’action (bean). Ajouter dans le fichier struts.xml au niveau de l’action appelée une balise « result » avec la valeur «input» Validation Struts (suite) Exemple : <action name="connection" class="pl.AuthentificationVA"> <result name="success" >accueil.jsp</result> <result name="error" >connect.jsp</result> <result name="input" >connect.jsp</result> </action> La balise « result » avec la valeur «input » doit renvoyer vers la page résultat ou nous voudrions afficher les messages d’erreur si les valeurs des champs ne sont pas valides. En général c’est la page qui a appelé l’action. Validation Struts (suite) Exemple : <validators> <field name="login"> <field-validator type="requiredstring"> <message> Le login est un champs obligatoire! </message> </field-validator> </field> </validators> Validation Struts (suite) <field name="login"> <field-validator type="requiredstring"> <message>Le login est un champs obligatoire!</message> </field-validator> <field-validator type="stringlength"> <param name="minLength">5</param> <param name="maxLength">10</param> <message> La longueur du login doit être comprise entre ${minLength} et ${maxLength} </message> </field-validator> <field-validator type="regex" > <param name="expression">[0-9]*[0-9]</param> <message> Le login doit être un entier </message> </field-validator> </field> Validation Struts (suite) Les classes de validation fournit dans le framework Struts par défaut : <validators> <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/> <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/> <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/> <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/> <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/> <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/> <validator name="fieldexpression class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/> <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/> <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/> <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/> <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/> <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/> </validators> Validation Struts (suite) required Permet de vérifier qu’un champ n’a pas de valeur null.une chaine de caractère vide n’est pas nulle. elle est présente mais vide, ce qui est différent. requiredstring Permet de tester si un champ n’a pas de valeur nulle, et non vide. Cette validation contient un paramètre trim qui correspond aux espaces avant et après la saisie. stringlength Permet de valider la taille d’un champ non vide. nous pouvons alors spécifier la taille minimale et maximale d’un champ de formulaire. int Cette validation permet de vérifier si un champ peut être converti en entier. On peut utiliser les paramètres min et max Double Cette validation permet de vérifier si un champ peut être converti en réel. On peut utiliser les paramètres min et max Validation Struts (suite) date Permet de vérifier si un champ est de type date et dans une certaine plage. e-mail permet de vérifier si un champ de type chaine de caractère regex Permet de vérifier les expression régulières connect.jsp accueil.jsp connection execute() consulteCommande consulterCommande() editAjoutCommande editAjouterCommande() consulteListeCommande.jsp ajoutCommande.jsp ajoutCommande ajouterCommande() editModifieCommande editModifierCommande() modifCommande modifierCommande() supprimeCommande supprimerCommande() ??? modifCommande.jsp connect.jsp accueil.jsp connection execute() lister_Commande lister() editer_Commande editer() listerCommande.jsp editerCommande.jsp ajouter_Commande ajouter() consulter_Commande consulter() modifier_Commande modifier() supprimer_Commande supprimer () consulterCommande.jsp Gestion dynamique des actions Un projet final contient plusieurs déclarations d’actions et limite parfois la lisibilité et la maintenabilité du fichier de configuration struts.xml Dans la première version de Struts, le fichier de configuration pouvait contenir beaucoup de ligne et parfois des déclarations d’actions quasiment identiques (exemple : gestion des articles, des clients, des comptes,…). Afin d’apporter des solutions à ces problèmes, Struts propose désormais des déclarations d’actions sous forme d’expressions régulière Gestion dynamique des actions Exemple : Factoriser les deux actions relatives à lister les commandes et éditer une commande <action name = "*_Commande" method = "{1}" class="pl.CommandeVA"> <result name="lister_editer" >{1}Commande.jsp</result> <result name="error" >error.jsp</result> </action> Gestion dynamique des actions Factoriser les actions relative à la gestion d’une entité commande : <action name="*_Commande" method="{1}" class="pl.CommandeVA"> <result name="lister_editer_consulter" >{1}Commande.jsp</result> <result name="ajout_modif_supp" >listerCommande.jsp</result> <result name="input" >editerCommande.jsp</result> <result name="error" >error.jsp</result> </action>