Développement Web avec J2EE

Transcription

Développement Web avec J2EE
CHAPITRE 2
Les servlets
Qu’est ce qu’une servlet ?
Les servlets sont la base de la programmation Web J2EE. Toute la conception d’un
site Web en Java repose sur ces éléments que sont les servlets.
Une servlet est un programme Java qui tourne sur la machine où est installé le serveur J2EE, et qui est invoqué lorsqu’un navigateur client appelle l’URL liée à ce programme. Une servlet n’est (en général) pas appelée directement, elle ne l’est qu’à travers une URL.
Par exemple, j’écris la servlet ServletCoucou.java (qui sera compilée en
ServletCoucou.class), et je décide que lorsque j’appelle la page HTML salut.htm, c’est la
servlet ServletCoucou.java qui s’exécute.
Bien entendu, il sera judicieux que la servlet ainsi invoquée produise un affichage
dans la page du navigateur, sinon on pourrait se demander s’il s’est réellement passé
quelque chose !!! En effet la page salut.htm n’est pas censée exister sur le serveur, elle
ne sert qu’à faire le lien avec la servlet, et donc tout le code HTML qui pourrait s’y
trouver (si par hasard cette page salut.htm existait) ne sera pas pris en compte.
On verra plus loin comment écrire une servlet (section "Ecriture d’une première
servlet", page 29).
Comment est effectué le lien entre la servlet et l’URL
Fichier web.xml
Le fichier web.xml est le fichier le plus important d’une application J2EE car il
contient le paramétrage des servlets de l’application.
Chaque servlet de l’application doit être décrite dans le fichier web.xml, et le lien de
la servlet avec l’URL y figure également.
26
Chapitre 2 — Les servlets
Ce fichier contiendrait pour l’exemple ci dessus :
Fichier web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>coucou</servlet-name>
<servlet-class>ServletCoucou</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>coucou</servlet-name>
<url-pattern>/salut.htm</url-pattern>
</servlet-mapping>
</web-app>
La déclaration de la servlet se fait dans l’élément XML <servlet> :
• <servlet-name> est le nom interne de la servlet, quelconque, mais qui l’identifie de façon unique.
• <servlet-class> est la classe Java associée à la servlet (qui, on le verra, doit
dériver de la classe HttpServlet).
Le lien entre l’URL et la servlet s’effectue grâce à l’élément <servlet-mapping> :
• <servlet-name> est le nom interne donné à la servlet (qui doit être identique
à celui indiqué dans l’élément <servlet>)
• <url-pattern> est l’URL permettant de faire le lien avec la servlet.
À chaque servlet de l’application doit correspondre un élément <servlet> dans le
fichier web.xml, sinon la servlet n’existera pas pour le serveur d’applications.
Par contre, l’élément <servlet-mapping> ne sert que si la servlet est invoquée à travers une URL.
Le fichier web.xml s’appelle le descripteur de déploiement. On peut y indiquer
autant de servlets que l’on veut.
Remarque : il peut sembler bizarre de devoir répéter l’élément <servlet-name> (une
fois dans l’élément <servlet>, une fois dans l’élément <servlet-mapping>). C’est que
la norme J2EE l’impose, le fichier web.xml devant être écrit selon un format bien spécifique (la DTD définie dans la directive DOCTYPE).
Il est possible, bien que cela ne soit pas fréquemment utilisé, d’avoir plusieurs
mappings pour une servlet. Pour cela, on les indique dans web.xml en utilisant l’élément <servlet-mapping> pour chacun d’eux.
Compatibilité entre les serveurs J2EE
Le fichier web.xml est certainement l’endroit où il y a le plus de problèmes de
compatibilité entre les serveurs J2EE.
En effet, certains serveurs exigent que l’URL indiquée dans <url-pattern> commence
par le caractère "/" (Tomcat), d’autres ne l’exigent pas (Jrun, Jboss).
Différentes manières d’invoquer une servlet
27
De même, certains serveurs exigent que le fichier web.xml indique la référence à une
DTD (directive DOCTYPE) (Jboss), d’autres ne l’exigent pas (Jrun, Tomcat).
Pour éviter tout problème, et assurer une compatibilité avec tous les serveurs J2EE
(du moins Jrun, Tomcat et Jboss) on écrira le fichier web.xml selon les règles les plus
contraignantes, sachant que si une règle est appliquée sans que cela soit nécessaire,
cela ne provoque pas de problèmes sur un serveur donné.
Différentes manières d’invoquer une servlet
Dans toute la suite on supposera qu’un serveur J2EE est actif, par exemple le serveur default
de Jrun. On a vu que ce serveur est accédé par le port 8100. Mais tout ce qui est expliqué
ci-après pourrait s’appliquer à n’importe quel serveur J2EE.
Par l’URL liée à la servlet
Nous avons vu une première manière qui est d’appeler dans le navigateur l’URL liée
à la servlet. Cela pourrait se traduire par la façon de procéder suivante :
On tape l’adresse suivante dans le navigateur : http://localhost:8100/salut.htm.
Ceci ne peut fonctionner que si le mapping de la servlet avec l’URL a été correctement effectué dans le fichier web.xml.
Remarquons que pour que la servlet soit appelée, l’URL peut aussi être accédée par
l’intermédiaire d’un lien, ou par l’intermédiaire d’un bouton de validation de formulaire (qui activerait la servlet).
Par l’appel direct de la servlet
Cette méthode d’appel direct de la servlet n’est pas portable, car elle dépend du système d’exploitation utilisé.
En effet sous Windows, on écrira : http://localhost:8100/servlet/ServletCoucou, tandis que
sous Linux on écrira : http://localhost:8100/servlet/coucou.
Dans un cas on utilise le contenu de <servlet-class>, dans l’autre on utilise le
contenu de <servlet-name>.
La racine "/servlet" indiquée dans "/servlet/ServletCoucou" ou dans "/servlet/coucou"
est obligatoire, et ne correspond pas à un répertoire sur le serveur.
Dans ce cas, on n’a pas besoin d’avoir effectué le mapping de la servlet dans web.xml.
Seule la déclaration de la servlet est obligatoire (par l’élément <servlet>).
Remarquons que l’appel direct à la servlet peut aussi être effectué par l’intermédiaire
d’un lien, ou par l’intermédiaire d’un bouton de validation de formulaire (qui activerait la servlet).
• Cas particulier de Tomcat : ce mécanisme (d’appel direct de la servlet) fonctionne pour tous les serveurs J2EE, mais Tomcat a un paramétrage par défaut
qui inhibe ce fonctionnement. Il faut donc paramétrer Tomcat pour que ce
mécanisme redevienne possible.
Pour cela, il faut modifier un fichier de configuration de Tomcat appelé web.xml,
mais qui n’est pas le même que celui décrit ci-dessus, car ce fichier est situé dans
le répertoire <rep install Tomcat>/conf (ce sont les concepteurs de Tomcat qui lui
28
Chapitre 2 — Les servlets
ont donné ce nom là, sans doute parce que des éléments XML ont le même
nom dans les deux fichiers).
Il faut supprimer les commentaires aux lignes suivantes, qui sont déjà présentes
dans le fichier web.xml (la mise en commentaires provoque l’inhibition du
mécanisme) :
Fichier <rep install Tomcat>/conf/web.xml
...
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
...
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
...
Une fois ces modifications effectuées dans le fichier web.xml, il est nécessaire de
relancer Tomcat pour que les modifications soient prises en compte.
Conclusion : cette méthode fonctionne mais n’est pas portable, donc il est préférable
de ne pas l’utiliser. On lui préférera celle utilisant le mapping avec une URL, d’abord
expliquée.
Répertoires internes d’un serveur J2EE
Un serveur J2EE doit avoir une structure interne correspondant à la norme J2EE
définie par SUN.
Le répertoire WEB-INF et tous ses sous-répertoires sont communs à tous les serveurs
J2EE suivants la norme J2EE. Par contre, les répertoires parents de WEB-INF sont
dépendants du serveur J2EE choisi.
Le répertoire classes contient les .class des servlets; le fichier web.xml est le descripteur
de déploiement.