16
Descripteur de déploiement Chapitres traités Application Web Lorsque nous avons étudiés les servlets, nous avons déjà rencontrés et utilisés les descripteurs de déploiement. Dans ce chapitre, nous allons découvrir un peu plus en détail toutes les subtilités de ce fichier particulier. Les descripteurs de déploiement sont fichiers XML contenant toutes les informations de configuration relatifs à une application Web. Pour chaque application Web, le descripteur de déploiement s'appelle <web.xml>. Par ailleurs, une application Web doit respecter une structure particuliere. Avant de rentrer dans le vif du sujet concernant le descripteur de déploiement, il me paraît primordial de connaître ce qu'est une application Web. Application Web Une application Web doit répondre à un certain nombre d'attente de la part du client. Elle est généralement composée d'un certain nombres d'éléments en interaction entre eux. Une application Web peut être relativement conséquente et être composée de beaucoup d' éléments. Elle peut posséder : plusieurs pages statiques <*.html>, plusieurs servlets, des pages JSP, des JavaBeans, des objets distribués de type EJB, des applets, etc. Cette complexité ne doit pas du tout apparaître pour le client. L'utilisation de l'application Web doit au contraire être la plus conviviale possible et sa structure totalement transparente. En fait, pour l'utilisateur, il doit juste proposer le nom de l'application Web, dans l'URL, à la suite du nom du site. http://NomDuSite/ApplicationWeb comme par exemple http://localhost:8080/FormulairePersonne Pour que cela soit aussi simple pour l'utilisateur, il est nécessaire d'avoir une architecture particulière, prédéfinie, qui sera la même pour toutes les applications Web de type Java. Structure d'une application Web <webapps> Une application web est donc visible par son nom d'appel dans l'URL lors de l'exécution d'un script. Elle correspond de façon cachée à une arborescence particulière des fichiers sur le disque dur. Cette arborescence possède une structure préétablie que nous devons respecter. Lorsque l'utilisateur se connecte sur le site, et grâce à cette organisation particulière, le serveur Web (Tomcat par exemple) va systématiquement procéder à la même démarche : 1. Recherche de la page d'accueil correspondant à l'application Web. C'est généralement une page Web statique et pour plus de souplesse elle porte le nom de <index.html>. Elle peut comporter un formulaire à remplir. (Il peut déjà y avoir aussi des pages Web dynamiques de type JSP ou servlets). Grâce au descripteur de déploiement <web.xml>, il est possible de définir n'importe quel fichier comme fichier d'accueil. Ainsi, au lien de <index.html>, nous pourrions définir la page d'accueil <login.jsp>. 2. Après validation du formulaire, le serveur Web, au travers de composants Web (servlet, JSP, EJB) fabrique une nouvelle page Web en correspondance de la saise réalisée par le client. L'utilisation et la situation du bon composant Web est indiquée par le descripteur de déploiement. Dans l'exemple ci-contre, nous faisons appel à la servlet <Formulaire.class>. Pour que tout se passe convenablement, il faut donc respecter l'architecture des dossiers, telle qu'elle vous est présentée dans le tableau ci-dessous : Dossiers Type de fichier webapp ressources Web publiques (pages accessibles directement) Pages statiques : <*.html> Pages dynamiques JSP : <*.jsp> Applets : <*.class> WEB-INF ressources Web privée (pages non accessibles directement) Fichier de configuration de l'application WEB : <web.xml> Fragment de pages : <*.jspf> Pages d'erreur : <*.jsp> classes Emplacement des servlets et des JavaBeans : <*.class>. Les servlets sont nécessairement compilées. tlds Bibliothèques de balises lib Bibliothèques <*.jar> non standards comme les drivers JBDC. Le tableau ci-dessus nous montre donc l'architecture à respecter pour mettre en oeuvre une application Web. Normalement, il est préférable qu'elle dispose d'un dossier personnel nommée ici <webapp>. Ce dossier peut prendre le nom que vous désirez comme FormulairePersonne. Généralement le nom choisi correspond au nom de l'application Web. .

Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

  • Upload
    vanmien

  • View
    237

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Descripteur de déploiement

Chapitres traités Application Web

Lorsque nous avons étudiés les servlets, nous avons déjà ren contrés et utilisés les descripteurs de déploiement. Dans c e chapitre, nousallons découvrir un peu plus en détail toutes les subtilités de ce fichier particulier.

Les descripteurs de déploiement sont fichiers XML contenant toutes les informations de configuration relati fs à une application Web.Pour chaque application Web, le descripteur de déploiement s'appelle <web.xml> . Par ailleurs, une application Web doit respecter unestructure particuliere. Avant de rentrer dans le vif du suje t concernant le descripteur de déploiement, il me paraît pri mordial de connaîtrece qu'est une application Web.

Application Web

Une application Web doit répondre à un certain nombre d'atte nte de la part du client. Elle est généralement composée d'un certain nombres d'éléments en interaction entreeux. Une application Web peut être relativement conséquent e et être composée de beaucoup d' éléments. Elle peut posséde r :

plusieurs pages statiques < *.html >,

plusieurs servlets ,

des pages JSP,

des JavaBeans ,

des objets distribués de type EJB,

des applets ,

etc.

Cette complexité ne doit pas du tout apparaître pour le client. L'utilisation de l'application Web doit au contraire être la plus conviviale possible et sa structuretotalement transparente. En fait, pour l'utilisateur, il doit juste proposer le nom de l'application Web, dans l'URL, à la suite du nom du site.

http://NomDuSite/ApplicationWeb comme par exemple http://localhost:8080/FormulairePersonne

Pour que cela soit aussi simple pour l'utilisateur, il est nécessaire d'avoir une architecture particulière, prédéfinie, qui sera la même pour toutes les applicationsWeb de type Java.

Structure d'une application Web <webapps>

Une application web est donc visible par son nom d'appel dans l'URL lors del'exécution d'un script. Elle correspond de façon cachée à une arborescenceparticulière des fichiers sur le disque dur. Cette arborescence possède unestructure préétablie que nous devons respecter.

Lorsque l'utilisateur se connecte sur le site, et grâce à cette organisationparticulière, le serveur Web (Tomcat par exemple) va systématiquement procéder àla même démarche :

1. Recherche de la page d'accueil correspondant à l'applica tion Web. C'estgénéralement une page Web statique et pour plus de souplesse elle porte lenom de <index.html> . Elle peut comporter un formulaire à remplir. (Il peut déjày avoir aussi des pages Web dynamiques de type JSP ou servlets ). Grâce audescripteur de déploiement <web.xml> , il est possible de définir n'importe quelfichier comme fichier d'accueil. Ainsi, au lien de <index.html> , nous pourrionsdéfinir la page d'accueil <login.jsp> .

2. Après validation du formulaire, le serveur Web, au traver s de composants Web(servlet , JSP, EJB) fabrique une nouvelle page Web en correspondance de lasaise réalisée par le client. L'utilisation et la situation du bon composant Webest indiquée par le descripteur de déploiement. Dans l'exem ple ci-contre, nousfaisons appel à la servlet <Formulaire.class> .

Pour que tout se passe convenablement, il faut donc respecter l'architecture desdossiers, telle qu'elle vous est présentée dans le tableau ci-dessous :

Dossiers Type de fichier

webapp

ressources Web publiques (pages accessiblesdirectement)Pages statiques : <*.html>Pages dynamiques JSP : <*.jsp>Applets : <*.class>

WEB-INF

ressources Web privée (pages non accessiblesdirectement)Fichier de configuration de l'application WEB :<web.xml>Fragment de pages : <*.jspf>Pages d'erreur : <*.jsp>

classesEmplacement des servlets et des JavaBeans :<*.class> .Les servlets sont nécessairement compilées.

tlds Bibliothèques de balises

libBibliothèques <*.jar> non standards comme lesdrivers JBDC.

Le tableau ci-dessus nous montre donc l'architecture à respecter pour mettre enoeuvre une application Web. Normalement, il est préférable qu'elle dispose d'undossier personnel nommée ici <webapp>.

Ce dossier peut prendre le nom que vous désirez comme FormulairePersonne . Généralement le nom choisi correspond au nom de l'applicat ion Web..

Page 2: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Partie publique <webapps> ou <FormulairePersonne>

Votre application Web se situe donc dans le répertoire qui servira au déploiement. Tous les fichiers qui se trouvent dans la racine de ce répertoire constitue lapartie publique de l'application, celle qui sera uniquement accessible directement par les clients Web potentiels. Au niveau de la racine, nous devons trouver aumoins la page d'accueil, plus quelques pages Web statiques ou dynamiques (JSP) qui ont un intérêt public. Se trouvent également les pages Web avec client"riche", c'est-à-dire celles qui comportent des applets. Les applets doivent donc se situer dans cette partie publique sinon elles ne seraient pas accessibles.

La page d'accueil est généralement, soit :

1. index.html

2. index.htm

3. index.jsp

Il est possible d'utiliser un autre nom de page d'accueil comme <Identification.html>. Il est alors nécessaire de le préciser dans la descripteur de déploiement.Dans l'extrême, nous pouvons donner une liste de pages d'accueil potentielles, mais la plupart du temps, nous indiquons dans ce descripteur juste la page quenous avons décidé de prendre.

Partie privée <WEB-INF>

Dans l'application Web se trouve systématiquement le répertoire <WEB-INF> qui est un répertoire spécial contenant toutes les informations de déploiement et lecode de l'application. Ce répertoire est protégé par le serveur Web, et son contenu est invisible, même si l'on rajoute /WEB-INF/ à L'URL de base. <WEB-INF> estdonc la partie privée de l'application Web et ne peut-être accessible que par décision des développeur au travers du descripteur de déploiement contenu dans cerépertoire. Toutefois, vos classes d'application peuvent charger des fichiers complémentaires directement à partir de cette zone, en utilisant la méthodegetResource( ), et c'est un endroit sûr pour stocker des ressources d'application.

Le répertoire <WEB-INF> contient le très important fichier <web.xml> qui est justement le descripteur de déploiement..

Répertoires <WEB-INF/classes> et <WEB-INF/lib>

Ces deux répertoires contiennent, respectivement, des fichiers de classes Java et les bibliothèques Jar.

Le répertoire <WEB-INF/classes> est automatiquement rajouté au chemin de classe de l'application Web, et chaque fichier de classes qui y est stockée est doncdisponible pour l'application. Nous y retrouvons spécialement les classes des servlets et des Javabeans.

Le répertoire <WEB-INF/lib> est utile pour stocker les bibliothèques nécessaires à l'application Web, mais qui ne font pas partie de JRE standard comme, parexemple, les pilotes JDBC.

Constitution du descripteur de déploiement

Pour chaque application Web, nous avons besoin d'un descrip teur de déploiement. Il est unique. Il s'agit d'un fichier XM L qui porte le nom de <web.xml> . Nous venons de levoir, ce fichier doit être placé dans le répertoire <WEB-INF> de l'application Web. <web.xml> est un fichier de configuration de l'application Web.

Ce descripteur de déploiement permet de recencer les compos ants Web ( servlets , JSP, EJB) qui font parti de l'application Web. Il permet également de maîtriser la gestiondes exceptions en proposant des pages d'erreur (Web) person nalisés suivant le type d'erreur survenu lors d'une mauvais e saisie du client. Il permet également de mettre enplace des filtres afin de recencer toutes les requêtes soumi ses par le client et ainsi de lancer le bon composant Web qui se ra adapté à la situation.

Elément du descripteur de déploiement

Ce document XML comporte l'élément racine <web-app>. Le descripteur de déploiement étant contenu dans un fichier XML, il doit être conforme à cettespécification. Il doit donc commencer par une déclaration XML suivi d'une déclaration DOCTYPE (jusqu'à la spécification Servlet 2.3) ou par un Schéma XML (àpartir de la spécification 2.4).

Sous-éléments du descripteur de déploiement

L'élément racine <web-app> dispose généralement d'un ou plusieurs sous-éléments suivant :

Elément Description

icon Le chemin d'accès a une icône qui peut être employée par un out il graphique pour représenter l'application Web.

display-name Un nom qui peut être employé par un outil de gestion d'applica tions pour représenter l'application Web.

description Une description de l'application.

distributable Indique si l'application peut être distribuée entre plusie urs serveurs. La valeur par défaut est false .

context-param Contient les valeurs des paramètres valables pour toute l'a pplication Web.

filter Définit une classe de filtre qui sera aplliquée avant la serv let.

filter-mapping Définit un alias pour un filtre.

listener Définit une classe de listener qui sera appelée par le conten eur à la survenue d'un événement particulier.

servlet Définit une servlet par son nom et sa classe.

servlet-mapping Définit un alias pour une servlet.

session-config Définit un délai maximal d'inactivité pour les sessions.

mime-mapping Définit une association entre les fichiers publics de l'app lication et des types MIME.

welcome-file-list Définit la ressource à retourner par défaut au client si aucu ne ressource n'est spécifiée.

error-page Définit la page d'erreur à retourner si aucune erreur partic ulière se produit.

Page 3: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

taglib Définit l'emplacement des bibliothèques de balises.

resource-env-ref Configure une ressource externe qui peut être utilisée par l a servlet.

resource-ref Configure une ressource externe qui peut être utilisée par l a servlet.

security-constraint Décrit les rôles des utilisateurs pouvant accéder à l'appli cation Web.

login-config Configure la méthode d'authentification.

security-role Définit un rôle de sécurité pour l'application.

env-entry Définit le nom d'une ressource accessible grâce à l'interfa ce JNDI.

ejb-ref Définit une référence distante à un Entreprise JavaBean (EJB).

ejb-local-ref Définit une référence locale à un EJB.

Nous ne ferons pas une étude exhaustive. Dans la suite, nous allons décrire un certain nombre de balises que vous serez succeptible de rencontrer ou d'utiliser.Nos premiers descripteurs de déploiement seront exploités à partir d'exemples simples. Nous commencerons par un exemple que nous étofferons au fur et àmesure.

Affichage de l'application Web : <display-name>

Cette balise représente tout simplement un nom qui peut être employé par un outil de gestion d'applications (comme le Gestionnaire d'applications WEB Tomcat ) pourreprésenter l'application Web. Elle n'a pas une grande impo rtance, mais cela peut être sympathique d'avoir une visuali sation sommaire de ce que réalise notre ApplicationWeb.

Définition des pages d'accueils : <welcome-file-list>

Cette balise permet de définir le document à retourner par dé faut au client si aucune ressource n'est spécifiée. Afin d'i llustrer l'intérêt de cette balise, nous allons prendrel'exemple de la page d'accueil ci-dessous située dans la par tie publique de notre application Web.

Page 4: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Pour accéder à cette page, le client Web, sur son URL, doit obligatoirement désigner en plus du nom du site et de l'application Web, le nom de la page Web àafficher. Ainsi, en effectuant le test sur l'ordinateur où se situe le serveur Web, nous devrions écrire :

http://localhost:8080/UneApplicationWeb/Identification.html

Cela impose que le client connaisse le nom de la page Web à afficher et doit en plus écrire une URL relativement longue. Il serait préférable que le client spécifieuniquement le nom de l'application Web sans qu'il se tracasse du nom de la page d'accueil qui est derrière. C'est au serveur Web à s'occuper de trouver la bonnepage à afficher automatiquement.

La première solution consiste, et nous en avons souvent parl er, de prendre comme nom de page d'accueil <index.html> . Seulement, il peut aussi être intéressant deconserver le nom de la page que nous avons choisi puisque ce no m est relativement évocateur.

C'est là qu'intervient le descripteur de déploiement. En effet, la balise <welcome-file-list> permet justement de spécifier l'ensemble des documents à ouvrirautomatiquement lorsque le client se contente de spécifier uniquement le nom de l'application Web dans son URL.

Lorsque le client devrait écrire uniquement ceci :

http://localhost:8080/UneApplicationWeb

Le serveur renvoie le premier document trouvé parmi ceux proposés de la liste donnée par la balise <welcome-file-list>. Chaque document est ensuite désigné parla balise <welcome-file>. Nous pouvons effectivement proposer plusieurs documents dans le cas où plusieurs solutions sont envisageables. Toutefois, dans lapratique, un seul document sera souvent suffisant.

<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file></welcome-file-list>

Dans cet exemple, <welcome-file-list> indique lorsqu'une requête partielle (chemin de répertoire) est reçue, le serveur doit d'abord chercher un fichier appelé<index.html> puis, en cas d'échec, un fichier appelé <index.htm> puis, de nouveau en cas d'échec, un fichier appelé <index.jsp>. Si aucun de ces fichiers n'esttrouvé, c'est au serveur de décider quelle page à afficher. En général, les serveurs sont configurés pour afficher une liste organisée comme un répertoire ou pourrenvoyer un message d'erreur.

Définition des servlets : <servlet>

L'élément <servlet> est l'un des plus important du descripteur de déploiement. I l permet de décrire les servlets de l'application Web. L'élé ment <servlet> indique auconteneur la classe qu'il doit associer au nom de la servlet. Eventuellement, l'élément <servlet-mapping> (qui est souvent en relation avec cet élément <servlet> ) associeune URL à ce nom.

L'élément <servlet> peut posséder les sous-éléments suivant :

<icon>

<servlet-name>

<display-name>

<description>

<servlet-class>

<jsp-file>

<init-param>

<load-on-startup>

<run-as>

<security-role-ref>

<servlet-name> et <servlet-class>

Les sous-éléments obligatoires sont <servlet-name> et un des éléments <servlet-class> ou <jsp-file> (Les pages JSP sont automatiquement compilées sousforme de servlets). L'élément <servlet-name> définit un nom qui peut être utilisé pour désigner la ressource. Les éléments <servlet-class> et <jsp-file>définissent les noms qualifiés de la classe de la servlet ou du fichier JSP.

Page 5: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

En définissant le nom de la servlet Identification et en utilisant l'élément <servlet-mapping> pour associer une URL /Identification au nom Identification, nouspouvons accéder à la servlet à l'aide de l'URL :

http://localhost:8080/UneApplicationWeb/Identification

Ce n'est pas ici une économie impressionnante, mais si le nom de la classe était web.entreprise.service.subdivision.Identification , il serait agréable de pouvoir yaccéder par un nom plus simple.

<load-on-start-up>

<servlet> <load-on-start-up>5</load-on-start-up> ...

</servlet>

L'élément <load-on-start-up> lorsqu'il est présent, contient un entier positif qui indique qu'il faut charger la servlet au démarrage du serveur. L'ordre dechargement des servlets est déterminé par cette valeur. Les servlets ayant la plus petite valeur sont chargées les premières. En cas de valeurs égales, l'ordre dechargement est arbitraire.

Si l'élément est absent, la servlet est chargée lors de la pre mière requêtes..

<init-param>

Une servlet possède une méthode init() qui est sollicité juste après sa création. Cette méthode permet à la servlet de lire les paramètres d'initialisation ou lesdonnées de configuration, d'initialiser des ressources externes telles des connexions à une base de données ou d'effectuer diverses autres tâches qui serontaccomplies une seule fois juste après la création de la servlet. La classe GenericServlet fournit deux formes de cette méthode :

public void init() throws ServletExceptionpublic void init(ServletConfig) throws ServletException

Le descripteur de déploiement peut définir des paramètres qui s'appliquent à la servlet au moyen de l'élément <init-param>. Le conteneur de servlets lit cesparamètres dans le fichier <web.xml> et les stocke sous forme de paires clé/valeur dans l'objet ServletConfig. L'interface Servlet ne définissant que init(ServletConfig), c'est cette méthode que le conteneur doit appeler. GenericServlet implémente cette méthode pour stocker la référence à ServletConfig puisappelle la méthode init( ) sans paramètres.

Aussi pour effectuer l'initialisation, nous avons seulement besoin de redéfinir init( ) sans paramètre. La référence à ServletConfig étant déjà mémorisée, laméthode init( ) a accès à tous les paramètres d'initialisation qui y sont stockées. Pour récupérer ces paramètres, il suffit d'utiliser la méthode getInitParameter(String).

public String GenericServlet.getInitParameter(String nomDuParamètre) ; // retourne la valeur du paramètre

L'intérêt des paramètres d'initialisation est de permettr e de changer de configuration sans avoir besoin de recompile r la servlet. Par exemple, vous pouvez placerdans le descripteur de déploiement, le nom du pilote du serve ur d'une base de données ainsi que sa localisation. Si plutar d, vous devez changer de serveur, il suffitde modifier les valeurs directement dans la balise <init-param> du descripteur de déploiement ( changement de texte ) sans recompiler la servlet qui a déjà été mis enoeuvre. Ainsi notre servlet fonctionne quelque soit le serv eur de base de données.

<init-param> est composé de deux sous-éléments qui correspondent respectivement au nom du paramètre suivi de sa valeur :

1. <param-name> : nom du paramètre

2. <param-value> : valeur du paramètre

Voici un exemple de paramètres initiaux définissant le serveur de base de données MySql définies dans le descripteur de déploiement associés à la servletFormulairePersonne :

Page 6: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Récupération de ses paramètres initiaux dans la servlet FormulairePersonne :

Pour cet exemple, nous avons utilisé la méthode getInitParameter( String ) à l'intérieur de la méthode init() . Il est possible de l'utiliser dans les autres méthodes de laservlet comme doGet() ou doPost() . Cela correspond alors à des paramètres moins spécifiques.

Association entre l'URL et la servlet : <servlet-mapping>

Cet élément est utilisé pour définir des associations entre des URL et des noms de servlets. Dans l'exemple ci-dessous, l 'URL /Identification est finalement associée à laclasse web.Identification par l'intermédiaire de l'alias proposé : Identification .

Il existe une association par défaut pour toutes les servlet s utilisées par Tomcat. Les URL correspondantes au schéma /servlet/* sont en effet transmises à uneservlet spéciale nommée invoker . Cette servlet lit les URL et transmet les requêtes aux servl ets correspondantes.

Mappage avec joker

<url-pattern>/Identification</url-pattern>

La balise <url-pattern> spécifiée dans l'exemple précédent était une simple chaîne, "/Identification". Pour ce modèle, seule une correspondance finissantexactement par "/Identification" invoquerait la servlet, comme l'URL suivante :

http://localhost:8080/UneApplicationWeb/Identification

La balise <url-pattern> permet d'utiliser des modèles beaucoup plus puissant, incluant même des caractères jokers. Par exemple, spécifier le mappage suivant :

<url-pattern>/Identifi*</url-pattern>

Page 7: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

permet à la servlet d'être invoquée par les URL suivantes :

http://localhost:8080/UneApplicationWeb/Identification ou http://localhost:8080/UneApplicationWeb/Identifier

Il est même possible de spécifier des caractères jockers suivis d'extensions, par exemple, <*.html> ou <*.perso>. Dans ce cas, la servlet peut être invoquée parn'importe quel chemin finissant par ces caractères.

Définition des paramètres de l'application Web : <context-param>

En imaginant que votre application Web dispose de plusieurs servlets qui font appel à la même base de données, il peut être génant de placer les mêmes paramètresd'initialisation <init-param> du pilote JDBC pour chacune de ces servlets. En effet, l'élém ent <init-param> défini dans le descripteur de déploiement, est associé à uneservlet en particulier. Il serait préférable d'utiliser pl utôt les paramètres d'initialisation de l'application Web , appelé paramètres de contexte <context-param> , qui sontaccessibles pour tous les composants Web constituant l'app lication Web.

<context-param>, comme pour <init-param> est composé de deux sous-éléments qui correspondent respectivement au nom du paramètre suivi de sa valeur :

1. <param-name> : nom du paramètre

2. <param-value> : valeur du paramètre

Pour que chacune des servlets récupèrent ces paramètres, il est nécessaire d'abord de solliciter l'objet correspondant au contexte de la servlet (plus précisément,au contexte de l'application Web) à l'aide de la méthode getServletContext(). Cet objet ensuite, peut délivrer les paramètres initiaux de l'application Web grâce àla méthode getInitParameter().

Gestion des exceptions - Pages d'erreur : <error-page>

Les exemples de servlets proposés jusqu'à présent consista it au maximum à enregistrer la trace dans un journal. C'est bi en pour l'administrateur, ça l'est beaucoup moinspour le client. Reprenons l'exemple précédent avec comme sc enario, le serveur de base de données non opérationnel. Voil à ce que reçoit le client lorsqu'il remplit leformulaire et qu'il envoie la requête au serveur :

Page 8: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Suivant les serveurs, l'utilisateur voit s'afficher la tra ce de l'exception ou alors il n'obtient aucune réponse du ser veur. Dans tous les cas, l'utilisateur a le sentiment quel'application est défectueuse, ce qui est le cas puisque pou r l'instant, il n'y a pas de véritable gestion d'exception.

Autre exemple, que se passe-t-il lorsque l'utilisateur sai sie une valeur non numérique dans le champ correspondant à l' âge ? Dans ce cas, le constructeur de la classeInteger lance une exception qui au niveau du client se traduit égalem ent par l'affichage de la trace de l'exception.

Cette situation n'est pas acceptable. Nous avertissons le c lient lorsque l'enregistrement c'est bien déroulé. Nous de vons également l'avertir lorsqu'un problème s'estrencontré et lui proposer une solution éventuelle, notamme nt lors de la mauvaise saisie d'un champ. C'est la moindre des choses. Bref, nous devons gérer l'exception.

Règle de bonne conduite : A moins que l'exception soit une IOException (communication interrompue) survenant lors de l'écriture de la réponse, le client devraittoujours recevoir une réponse intelligible.

Les pages d'erreur : <error-page>

La solution au problème que nous venons d'évoquer pourrait être de ne placer un bloc try...catch qu'autour des instructions susceptibles de lancer des exceptionsou d'ajouter des instructions d'affichage dans le bloc catch pour retourner une réponse spécifique en cas d'erreur. C'est effectivement une solution plausible, maisle code de la servlet devient relativement surchargé. Il est préférable de séparer le code du fonctionnement normal de la servlet, avec le code relatif aux problèmesrencontrés, grâce à des pages spécialisées qui s'appellent des pages d'erreur.

Il est possible de définir des pages Web ou des pages JSP qui se ront retournées au client suivant le type d'erreur survenu. Ainsi, le client sait toujours à quoi s'entenir quelque soit le scenario rencontré. Chaque page corre spond donc a un type d'erreur. Il faut que le développeur indi que quel est la page qui doit être envoyée auclient au regard de l'exception lancée. Il le définit, tout s implement, à l'aide du descripteur de déploiement.

Ainsi, lorsqu'un problème survient, le conteneur de servlets activera une page d'erreur d'une part, suivant l'exception qui est lancée, et d'autre part suivant ce quedécrit le descripteur de déploiement au regard de cette exception.

Dans le descripteur de déploiement, l'élément qui décrit les pages d'erreur est <error-page>.

Deux scenarii sont possibles. Soit nous indiquons le type d'erreur exacte, soit un code d'erreur délivré par le protocole HTTP (500 par exemple) qui correspondalors à une erreur plus générique. Le conteneur de servlets prend toujours, dans le descripteur de déploiement, en premier la page qui correspond pile à l'erreur.S'il ne la trouve pas, il se rabat alors sur le code d'erreur qui englobe un ensemble d'erreurs potentielles.

Sous-éléments de <error-page> : <exception-type> et <code-type>

Nous avons donc deux écritures possibles dans le descripteur de déploiement qui correspondent au deux scenarii. C'est le choix des sous-éléments de <error-page> qui détermine le scenario choisi. Ainsi nous pouvons avoir les sous-éléments suivants :

<error-page><exception-type>java.lang.NumberFormatException</exception-type><location>/WEB-INF/NombreIncorrect.html</location>

</error-page>

ou/et les sous-éléments suivant :

Page 9: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

<error-page><code-type>500</exception-type><location>/WEB-INF/ErreurServeur.html</location>

</error-page>

La première écriture indique que si une erreur de type numérique intervient, c'est la page <NombreIncorrect.html> qui va être envoyée au client. Dans ledeuxième cas, c'est l'erreur 500 donnée par le protocole HTTP qui permet d'envoyer au client la page <ErreurServeur.html>.

L'erreur 500 devrait systématiquement être traitée de cette façon. Ce co de indique une erreur interne du serveur que celui-ci ne peut traiter. Il peut s'agir d'unproblème de compilation d'une JSP ou d'une exception dans un e servlet.

En spécifiant une page d'erreur, vous vous assurez que le cli ent recevra une page lisible et correctement mis en forme, pl utôt qu'une trace cabalistique..

Localisation des pages d'erreur : <location>

L'élément <location> permet de déterminer quelle est la page qui doit être affichée au client. C'est le serveur qui l'envoie. Ce n'est pas le client qui l'utilisedirectement. Les pages d'erreur doivent donc être inaccessible de l'extérieur et doivent du coup être placée dans la zone privée de l'application Web, c'est-à-diredans le répertoire <WEB-INF>.

Descripteur de déploiement

NombreIncorrect.html

Page 10: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

ErreurServeur.html

Sécurité et authentification

Avec l'API Servlet 2.3, l'une des fonctionnalité les plus pu issantes dans une application Web est la possibilité de défi nir des contraintes de sécurité déclarative. Par sécuritédéclarative, on entend le fait qu'il suffit de décrire dans v otre fichier web.xml les parties de votre application Web ( accès à des documents, répertoires, servlets, etc. ) quisont protégés par mot de passe, le type d'utilisateurs autor isés à y accéder et la classe du protocole de sécurité nécessa ire aux communications ( crypté ou pas ).

Pour implémenter ces procédures de sécurité de base, il n'es t pas nécessaire d'ajouter du code à vos servlets..

Deux types d'entrées du fichier web.xml contrôlent la sécurité et l'authentification (avec toutef ois un troisème pour la définition du rôle) :

1. <security-contraint> : qui fournissent des autorisations basées sur les rôles uti lisateurs et, si vous le souhaitez, sur le transport sécuris é de données.

2. <login-config> : qui détermine le type d'authentification utilisée pour l' application Web.

3. <security-role> : qui définit un rôle de sécurité pour l'application web. ( A placer avant la balise <security-contraint> ).

Attribution de rôles aux utilisateurs

Revenons sur notre application Web Personnel. Je désire que cette application Web ne soit accessible que par login et mot de passe. L'extrait suivant du fichierweb.xml définit une zone appelée Application sécurisée, à partir d'un modèle d'URL “/” et précise que seul les utilisateurs possédant le rôle personnel peuvent yaccéder.

Il utilise la forme la plus simple du processus de connexion : le modèle d'identification BASIC, qui affiche dans le navigateur une simple boîte de dialoguenom d'utilisateur/mot de passe :

Page 11: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Ici, le modèle d'URL est “/” , ce qui signifie que toute l'application Web est sécurisée. Nous pourrions sécuriser qu'une seule partie de l'applicat ion Web, par exempleun répertoire de l'application qui ne sera accessible que pa r mot de passe.

Soit, par exemple, le répertoire secret qui devrait être sécurisé, il faudrait alors préciser le modèle d'URL suivant :

<url-pattern>/secret/</url-pattern>

L'entrée de contrainte de sécurité apparaît donc dans le fichier web.xml après toutes les entrées relatives à la servlet et au filtre. Chaque bloc <security-constraint> contient une section <web-ressource-collection> qui fournit une liste nommée de modèle d'URL d'accès à certaines zones de l'application Web, suivied'une section <auth-contraint> listant les rôles utilisateur autorisés à accéder à ces zones, au moyen des balises successives <role-name>.

Toutefois, pour que la section <auth-contraint> soit efficace, il est préférable que ces rôles aient été préa lablement définies, en dehors de la balise <security-contraint> , au moyen de la balise <security-role> à l'intérieur de laquelle se trouve également une suite de ba lises <role-name> .

<security-role><role-name>personnel</role-name>

</security-role><security-constraint>

...<auth-constraint>

<role-name>personnel</role-name></auth-constraint>

</security-constraint>

Attention : Avant que cela fonctionne, il reste toutefois une étape à fr anchir : créer le rôle utilisateur "personnel" , ainsi qu'un véritable utilisateur "Emmanuel"possédant ce rôle dans votre serveur d'application.

Dans le serveur Tomcat, il est facile d'ajouter des utilisat eurs et d'attribuer des rôles ; il suffit d'éditer le fichier conf/tomcat-users.xml . En voici un exemple ci-dessous avec l'ajout d'un seul utilisateur (N'oubliez pas d e fabriquer le rôle).

Le droit d'accès à des zones protégées est accordé à des rôles d'utilisateur et non pas à des utilisateurs individuels. Un rôle utilisateur représente en fait ungroupe d'utilisateurs. Au lien d'allouer les droits à chaque utilisateur, par nom, on les alloue à des rôles, les utilisateurs se voyant attribuer un ou plusieurs rôles.C'est le cas notamment ci-dessus avec l'utilisateur admin qui peut aussi bien jouer le rôle de gestionnaire d'application Web (manager) que le rôled'administrateur (admin) du serveur web Tomcat.

Lorsqu'un utilisateur essaie d'accéder à une zone protégée par mot de passe, le login est testé afin de vérifier s'il poss ède le rôle adéquat..

Transport de données sécurisées

Pour que votre application Web soit parfaitement sécurisée , il faudrait également protéger les informations qui trans itent sur le réseau. Il nous faut donc aborder un élémentsupplémentaire de la contrainte de sécurité : la garantie de transport. Chaque bloc <security-contraint> peut finir par une entrée <user-data-contraint> , qui indique lequeldes trois niveaux de sécurité de transport est retenu pour le protocole utilisé lors du transfert de données de et vers la z one protégées.

Page 12: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Les trois niveaux de sécurité sont :

1. NONE : qui est équivalent à une sortie de section , sans transport s pécial. C'est le mode standard pour le trafic web, qui en géné ral véhicule du texte plein via leréseau.

2. INTEGRAL : précise que le protocole de transport utilisé doit garanti r que les données envoyées ne sont pas modifiées durant le tra nsit. Ceci implique l'utilisationde signatures digitales ou de tout autre méthode de validation des données à l'arrivé e, mais n'impose pas que les données soient chiffrées et cach ées durant letransport.

3. CONFIDENTIAL : ajoute le chiffrement à la méthode INTEGRAL . En pratique, le seul mode de transport sécurisé largement u tilisé dans les navigateurs web est SSL.Exiger une garantie de transport autre que NONE impose l'utilisation du SSL au navigateur client.

Authentification des utilisateurs

La section <login-config> détermine exactement comment un utilisateur s'authentifi e à l'entrée de la zone protégée. La balise <auth-method> permet d'utiliser quatre typesd'authentification :

1. BASIC : utilise la boîte de dialogue standard "nom/mot de passe" du navigateur web. L'authentification BASIC envoie le nom et le mot de passe utilisateur en texteplein sur le réseau , à moins qu'une garantie de transport n'ait été utilisée sép arément pour démarrer SSL et chiffrer le stream de données.

2. DIGEST : est une variante de BASIC qui cache le texte de mot de passe mais n'est pas vraiment beau coup plus sécurisée ; elle est peu utilisée.

3. FORM : est équivalente à BASIC, mais permet d'utiliser, au lieu de la boîte de dialogue standard , son propre formulaire HTML ou servlet.

4. CLIENT-CERT : est une option intéressante. Elle impose que l'utilisateu r soit identifié via un certificat de clé publique côté client. Ceci implique l'utilisation d'unprotocole comme SSL, qui permet des échanges sécurisés et l'authentification m utuelle en utilisant des certificats numériques.

La méthode FORM est la plus utilisée car elle permet de personnaliser la page de connexion (nous vous recommandonsl'usage de SSL afin de sécuriser le stream de données. Il est également poss ible de spécifier une page d'erreur en casd'échec de l'authentification.

Page 13: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Les filtres de servlet

La servlet "Formulaire.java" que nous avons mis en oeuvre est relativement sophistiquée p uisqu'elle intègre le stockage des informations, saisie pa r l'opérateur, dans labase de données. Cette servlet intègre également la journal isation des requêtes dans un fichier journal mémorisant tou tes les tentatives d'accès. Pour cette journalisation,nous avons dû modifier la servlet en ce sens, la recompiler et la redéployer. C'est alors que l'on (votre patron, ou votre c lient) va vous demander de modifier l'applicationpour que le journal soit enregistré dans une base de données. Il vous faudra modifier de nouveau la servlet, la compiler, l a déployer... C'est alors que l'on va vousdemander ...

Bientôt, votre servlet sera remplie de code utile mais pas ex actement en rapport avec sa fonction initiale : recevoir les requêtes et répondre aux clients. Nous avonsbesoin d'une solution plus efficace.

Rôle des filtres

Les filtres sont un moyen permettant de donner à une application une structure modulaire. Ils permettent d'encapsuler différentes tâches annexes qui peuvent êtreindispensables pour traiter les requêtes. Ainsi, dans notre exemple, nous pouvons créer un filtre prévu uniquement pour la journalisation des événements, alorsque la servlet principale s'occupe du traitement de la requête proprement dite. Grâce à cette modularité, il devient facile de modifier le comportement del'application Web en modifiant uniquement son descripteur de déploiement.

La fonction principale d'une servlet consiste uniquement à recevoir des requêtes et répondre aux clients. Toute autre a ctivité annexe est du ressort d'une autreclasse. Aussi, lorsque que vous avez à implémenter une fonct ion particuliere, vous pouvez tirer profit des filtres et de la façon dont ils permettent d'encapsuler cestraitements spécifiques. Par ailleurs, leur modularité le ur permet d'être utilisés avec plusieurs servlets différen tes, ce qui facilite la maintenance en évitant laduplication du code.

Structuration des filtres

Les filtres sont chaînés, ce qui signifie que lorsque nous appliquons plus d'un filtre, la requête du serveur est passée à travers chacun d'eux de manièreséquentielle, chacun ayant l'opportunité d'agir dessus ou de la modifier (notion de filtre) avant de passer au prochain. De manière similaire, à l'exécution, lerésultat de la servlet est repassée à travers la chaîne en sens inverse. Il est donc possible au travers des filtres de modifier également la réponse de la servlet,même si le cas le plus fréquent consiste plutôt à faire des traitements au niveau de la requête. L'ordre des filtres de la chaîne est spécifié dans le descripteur dedéploiement.

Lorsque la méthode doFilter() d'un filtre est appelée, un des arguments passés est une référence à un objet de type FilterChain. Lorsque le filtre appellechain.doFilter(), le filtre suivant la chaîne est exécuté. Le code placé avant chain.doFilter() est exécuté avant le traitement de la servlet (ou d'un autre filtre).Toute modification que le filtre doit apporter à la requête doit donc être effectué avant cet appel. Le code placé après cet appel est exécuté après le traitement dela servlet. C'est donc là que doivent être effectuées toutes les modifications à apporter à la réponse. Si le filtre doit agir sur la requête et sur la réponse, ilcontiendra donc du code avant et après l'invocation de la méthode chain.doFilter().

Page 14: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Par ailleurs, si l'un des filtres doit interrompre le traite ment (par exemple en cas d'échec de l'authentification d'un client implémenté dans le prmier filtre), il peut lefaire simplement en n'appelant pas la méthode doFilter() .

Les filtres de servlet peuvent opérer sur tout type de requêt es d'une application Web, pas seulement sur celles gérées pa r des servlets. Ils peuvent également êtreappliqués à du contenu statique. Finalement ils peuvent êtr e utilisés pour tous les composants Web : Servlet , JSP, EJB et HTML.

Création d'un filtre

Pour créer un filtre pour notre application Web, nous devons accomplir deux tâches. La première consiste à écrire une classe implémentant l'interface Filter, laseconde à modifier le descripteur de déploiement de l'application pour indiquer au conteneur qu'il doit utiliser le filtre.

L'API Filter comporte trois interfaces : Filter, FilterChain, et FilterConfig. javax.servlet.Filter est l'interface implémntée par les filtres. Elle déclare trois méthodes :

1. void init (FilterConfig filterConfig ) : Cette méthode est appelée par le conteneur pour indiquer au filtre qu'il est mis en service.

2. void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) : Cette est appelée par le conteneur chaque fois qu'une paire requête/réponseest traitée pour un client.

3. void destroy ( ) : Cette méthode est appelée par le conteneur pour indiquer au filtre qu'il est mis hors service.

Vous pouvez constater que cette interface ressemble beaucoup à l'interface Servlet. Vous ne serez donc sûrement pas surpris d'apprendre que le cycle de vie desfiltres ressemble également beaucoup à celui des servlets :

1. Lorsqu'un filtre est créé, le conteneur appelle sa méthod e init() . Dans cette méthode, nous pouvons accéder aux paramètres d' initialisation grâce à l'interfaceFilterConfig . Toutefois, contrairement aux servlets, il n'est pas possi ble d'accéder à FilterConfig dans la méthode doFilter() sans en avoir préalablement enregistréune référence.

2. Lors du traitement de la requête, le conteneur appelle la m éthode doFilter() .

3. Avant de détuire le filtre, le conteneur appelle sa méthod e destroy() .

L'interface javax.servlet.FilterChain représente une chaîne de filtres. Elle déclare une méthode que chaque filtre peut invoquer pour appeler le filtre suivant dansla chaîne :

void doFilter (ServletRequest request, ServletResponse response) : Cette méthode entraine l'appel du filtre suivant dans la ch aîne. Si le filtre appelant est le dernier dela chaîne, la ressource cible de la requête est appelée (par e xemple une servlet).

Lorsque la méthode doFilter() d'un filtre est appelée, un des arguments passés est une référence à un objet de type FilterChain. Lorsque le filtre appellechain.doFilter(), le filtre suivant la chaîne est exécuté.

Descripteur de déploiement

Le descripteur de déploiement est utilisé pour indiquer au conteneur le ou les filtres qu'il doit appeler pour chaque servlet de l'application. Deux éléments sontutilisés pour décrire les filtres et indiquer à quelles servlets, ils doivent être appliqués.

Le premier est <filter>. Voici un exemple de <filter> contenant tous les sous-éléments possibles :

<filter><icon>Chemin d'accès à une icône</icon><filter-name>Le nom du filtre pour l'application Web</filter-name><display-name>Le nom utilisé par le gestionnaire d'application Web</display-name><description>Une description de l'application</description><filter-class>Le nom qualifié de la classe filtre</filter-class><init-param>

<param-name>nom du paramètre</param-name><param-value>valeur du paramètre</param-value>

</init-param></filter>

Seuls les sous-éléments <filter-name> et <filter-class> sont requis. Si un élément <init-param> est employé, les sous-éléments <param-name> et <param-value>doivent être présents. Ces paramètres sont accessibles grâ ce à l'interface FilterConfig .

Le second élément est filter-mapping. Il peut prendre une des deux formes suivantes :

<filter-mapping><filter-name>Même nom que pour l'élément filter</filter-name><url-pattern>Schéma d'URL auquel le filtre doit être appliqué</url-pattern>

</filter-mapping>

ou

<filter-mapping><filter-name>Même nom que pour l'élément filter</filter-name><servlet-name>Nom de la servlet auquel le filtre doit être appliqué</servlet-name>

</filter-mapping>

N'oubliez pas que l'ordre des éléments dans le descripteur d e déploiement est important. Les éléments <filter> doivent être placés avant les éléments <filter-mapping> qui doivent se trouver avant les éléments <servlet> .

Si plusieurs filtres sont nécessaires, ils doivent être présentés par des éléments <filter-mapping> séparés. Les filtres sont appliqués dans l'ordre du descripteur dedéploiment.

<filter-mapping><filter-name>FiltreB</filter-name><servlet-name>Formulaire</servlet-name>

</filter-mapping>

<filter-mapping><filter-name>FiltreA<filter-name><servlet-name>Formulaire</servlet-name>

</filter-mapping>

Toute requête adressée à la servlet Formulaire est d'abord envoyée à FiltreB, car il est le premier dans le descripteur de déploiement. Lorsque FiltreB invoque laméthode chain.doFilter(), le FiltreA est appelé. Lorsque ce dernier invoque lui-même la méthode chain.doFilter(), la servlet Formulaire est enfin exécutée.

Mise en oeuvre

Page 15: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Nous allons reprendre l'application Web précédente, et nou s allons modifier son comportement. En effet, souvenez-vou s, dans la servlet Formulaire, nous avions placée lajournalisation des événements - grâce à la méthode log() . Ce n'est pas du tout le but de cette servlet qui doit s'occupe r avant tout de la sauvegarde des informations saisiespar l'opérateur dans la base de données.

Nous allons donc mettre en oeuvre un filtre qui va s'occuper uniquement de cette journalisation. De plus, nous allons faire en sorte que cette journalisation, doncce filtre, soit lancée pour tous les composants qui constitue notre application Web. Ainsi, il sera possible de contrôler précisément le parcours de l'opérateur.

L'exemple ci-dessous nous montre le passage de l'opérateur par la page d'accueil "Formulaire.html" , la confirmation de sa saisie grâce à la servlet"Confirmation.java" ainsi que l'enregistrement définitif au moyen de la servlet "Formulaire.java" .

Nous enlevons toutes les commandes log() de la servlet "Formulaire.java" et nous les plaçons dans le filtre "Journal.java" implémenté ci-dessous :

Vous remarquez que les méthodes log() ont été supplantées par les méthodes println() sur la sortie standard. Le journal ainsi créé est représenté alors par le fichierstdout.log , comme vous l'avez vu d'ailleurs sur le journal d'exemple.

Page 16: Descripteurdedéploiement - programmation-java.1sur1.comprogrammation-java.1sur1.com/Java/Tutoriels/J2EE/PDF/Descripteur.pdf · taglib Définit l'emplacement des bibliothèques de

Voici ce que devient la servlet "Formulaire.java" sans les méthodes log() :

Attention , n'oubliez pas de compléter le descripteur de déploiement p our que ce filtre soit utilisé. Si vous désirez que tous les él éments de l'application Web activentle filtre avant d'être lancés, il suffit de prendre plutôt la balise <url-pattern> dans la mapping de filtre et de placer l'URL suivante : /* (le joker spécifie bien la prise encompte de tous les éléments).