Introduction aux servlets

publicité
SESSION
3
Introduction aux servlets
Programme de la session
✔ Principes de fonctionnement des servlets
✔ Création d'une première servlet minimale
✔ Les servlets et les pages JSP résultantes
Avant de nous plonger dans les détails de la rédaction d'une page JSP,
il sera profitable de connaître les grandes lignes du fonctionnement des
servlets, car ces petits programmes exécutés côté serveur constituent le
soubassement de JSP. Une servlet est un programme écrit en langage
Java et capable de répondre à une requête HTTP, tout comme le font les
programmes CGI (Common Gateway Interface), actuellement très répandus. A la différence du CGI, une servlet peut profiter des caractéristiques
évoluées du langage Java, comme l'exécution distribuée multithread
(un processus peut lancer l'exécution de plusieurs sous-processus simultanés) et la notion de session (permettant de conserver les valeurs des
données d'une session utilisateur d'une requête à l'autre). Chaque page
JSP que vous rédigerez finira par produire une servlet Java capable de
recevoir une requête HTTP et de renvoyer une réponse HTTP.
30
JSP Web Training
Principes de fonctionnement des servlets
Une servlet, (prononcez servlette) tout comme une applet (prononcez
applette), est un programme écrit en langage Java. Une applet est un
programme qui s'exécute sur la machine du client (le visiteur) après
avoir été rapatriée (téléchargée) depuis le site du serveur ; l'exécution
est réalisée sous le contrôle de la machine virtuelle JVM (Java Virtual
Machine) intégrée au navigateur. Une applet ne comporte pas obligatoirement de partie visuelle, mais presque toutes en ont une. La taille n'est
pas limitée mais, dans la pratique, les applets restent de taille réduite
pour ne pas entraîner des temps de téléchargement inacceptables pour
le visiteur. En revanche, une servlet n'est jamais téléchargée ; elle réside
et est exécutée sur le serveur. Vous pouvez considérer les servlets comme une infrastructure pour les applications Web se servant de Java. Une
servlet a accès à toutes les fonctions des interfaces de programmation
API de Java ; elle est donc indépendante de la plate-forme d'exécution
et peut aisément servir à enrichir les capacités fonctionnelles de la plupart des logiciels serveurs Web.
Une servlet se distingue d'une application Java classique de par ses capacités à gérer les requêtes HTTP. Une telle requête est émise par le navigateur du client suite au clic d'un lien hypertexte, à l'envoi d'un
formulaire, ou encore à la saisie d'une adresse URL dans un champ approprié.
Pour d'autres détails au sujet de HTTP, voyez le
Chapitre 19.
Lorsqu'un serveur Web reçoit une requête HTTP, il analyse la chaîne
d'adresse URL demandée pour savoir quel type de page a été demandé
par le navigateur. Si le navigateur a demandé une servlet, le serveur Web
transmet la requête au conteneur de servlets. Le programme conteneur
gère la création, l'utilisation et la destruction des servlets, soit le cycle
de vie de ces servlets. Le conteneur de servlets que nous allons utiliser
tout au long de ce livre est Tomcat (installé lors du Chapitre 2).
Pour chaque demande d'exécution d'une servlet via une requête HTTP,
le conteneur charge la servlet en mémoire et crée un objet instance à
partir de la classe nommée Servlet. Le conteneur n'a plus ensuite qu'à
Session 3 - Introduction aux servlets
31
lancer l'exécution de la servlet en l'initialisant par appel à la méthode
init() de la partie interface nommée Servlet, tout en lui transmettant un
objet ServletConfig en paramètre. L'objet ServletConfig contient des informations de configuration sous forme de paires nom/valeur ; ces valeurs
sont reçues et exploitées par la servlet.
Une fois la servlet correctement initialisée (la méthode init() s'est terminée sans erreur), la servlet peut traiter la requête HTTP et générer sa
réponse HTTP. La méthode service() transmet les deux objets
ServletRequest et ServletResponse à la servlet. Sauf mention contraire explicite, le conteneur de servlets travaille en mode multithread (sousprocessus multiples), ce qui lui permet de gérer plusieurs requêtes en
parallèle, en distribuant les requêtes à la servlet sous forme de sous-processus (threads) distincts, comme le montre la Figure 3-1.
Figure 3-1
Une même instance de servlet sait gérer plusieurs requêtes.
L'autre mode de fonctionnement consiste à utiliser l'interface nommée
SingleThreadModel. Dans ce cas, les requêtes sont mises en file d'attente
pour être exécutées l'une après l'autre (Figure 3-2).
32
JSP Web Training
Figure 3-2
Avec l'interface SingleThreadModel, la servlet répond aux requêtes l'une après
l'autre.
Une fois toutes les requêtes en attente servies, le conteneur de servlets
appelle la méthode destroy() pour libérer l'espace mémoire de l'objet servlet devenu inutile. Dès l'arrivée d'une nouvelle requête concernant lamême servlet, le processus reprend au début.
Création d'une première servlet minimale
Le Listing 3-1 propose de créer une servlet minimale qui se contente
d'afficher un message dans la fenêtre du navigateur.
Servez-vous des instructions suivantes pour compiler et exécuter ce premier exemple.
Session 3 - Introduction aux servlets
33
Listing 3-1
La servlet SalutMonde.java affiche un message.
/** SalutMonde (traduit de HelloWorld) **/
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SalutMonde extends HttpServlet
{
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException,
IOException
{
PrintWriter out = response.getWriter();
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>");
out.println("Exemple de servlet minimale SalutMonde");
out.println("</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<H1>Salut à tout le monde</H1>");
out.println("</BODY>");
out.println("</HTML>");
}
}
1. Saisissez le code source ci-dessus dans un éditeur de texte et
enregistrez le fichier dans le sous-répertoire <Tomcat>\webapps\
ROOT\WEB-INF\classes sous le nom SalutMonde et avec l'extension
de nom de fichier .java. Ce fichier .java servira de source pour la
compilation de la servlet. Vous pouvez aussi récupérer le fichier
dans le sous-répertoire sources\jsc_03 du CD-ROM.
2. Avant de compiler le fichier .java pour produire un fichier .class,
vérifiez que la variable CLASSPATH comporte bien une mention relative au fichier servlet.jar fourni avec Tomcat, fichier qui est nécessaire à la compilation. Si vous avez par exemple installé Tomcat
dans C:\JAKARTA, CLASSPATH doit comporter une chaîne
34
JSP Web Training
C:\JAKARTA\lib\servlet.jar. Revoyez le Chapitre 2 si nécessaire en ce
qui concerne la définition des variables d'environnement.
3. Ouvrez une fenêtre de ligne de commande (Commandes MS-DOS
sous Windows) et utilisez des commandes DOS pour aller dans le
sous-répertoire des classes du serveur Tomcat (<Tomcat>\webapps\
ROOT\WEB-INF\classes). Saisissez alors la ligne de commande de
compilation suivante :
javac SalutMonde.java
Si aucune erreur n'apparaît, la servlet est compilée. Si une erreur
survient, vérifiez d'abord que vous n'avez pas fait de faute de frappe dans le programme source ou sur la ligne de commande. Vérifiez la variable CLASSPATH. Une fois la compilation achevée, listez
le contenu du répertoire ; vous devez trouver un fichier nommé
SalutMonde.class. C'est la servlet compilée.
4. S'il a été lancé, arrêtez et redémarrez Tomcat. (lancez shutdown.bat
puis startup.bat du sous-répertoire <Tomcat>\bin).
5. Il suffit maintenant de démarrer votre navigateur et de préciser le
mot "servlet" après le nom de domaine pour indiquer à Tomcat que
nous désirons solliciter le conteneur de servlets. Pour accéder à
notre servlet (en supposant que Tomcat utilise le port 8080), saisissez l'adresse suivante :
http://localhost:8080/servlet/SalutMonde
N'ajoutez surtout pas l'extension de nom .class. Vous devriez obtenir ce que montre la Figure 3-3.
La première partie de SalutMonde.java réunit les instructions d'importation. Le paquetage nommé java.io contient l'objet PrintWriter, qui sera
appelé plus tard lors de l'exécution. Les deux autres paquetages,
javax.servlet.* et javax.servlet.http.*, offrent le support de l'interface API.
Nous vous ferons remarquer que javax.servlet.http.* se trouve en fait incorporé à javax.servlet.* (défini d'abord). Ce paquetage requiert pourtant
une instruction import spécifique, car l'interface API des servlets sait gérer d'autres servlets en plus de celle correspondant au protocole HTTP.
Session 3 - Introduction aux servlets
35
Figure 3-3
Résultat de l'exécution de la servlet minimale.
Vous aurez remarqué que les deuxième et troisième paquetages commencent par javax et non java. Les servlets ne
font en effet pas partie des classes Java fondamentales
définies pour ce langage ; ce sont des classes spécialisées
qui viennent en extension des classes fondamentales, d'où
le x ajouté.
La seconde partie du programme correspond aux déclarations de classes.
La servlet SalutMonde dérive de la classe HttpServlet, et en hérite donc
toutes les méthodes et propriétés. C'est le cas de la plupart des servlets :
elles dérivent de la classe HttpServlet définie dans le paquetage
javax.servlet.http.
La déclaration de classe contient la déclaration de méthode doGet(), qui
se charge de traiter les requêtes GET reçues des navigateurs Web. Cette
méthode doGet() est définie dans la superclasse HttpServlet ; elle attend
deux paramètres d'entrée et sait déclencher deux exceptions. Les deux
paramètres sont HttpServletRequest et HttpServletResponse. Leur valeur
est générée par le moteur JSP lorsqu'il reçoit chaque requête HTTP. Une
fois appelés, les objets deviennent accessibles à la servlet. L'objet
HttpServletRequest contient des informations concernant la requête
HTTP émise par le navigateur, alors que l'objet HttpServletResponse contient celles relatives aux réponses HTTP.
36
JSP Web Training
La classe dérivée (sous-classe) SalutMonde surcharge (redéfinit) la méthode doGet(), dont elle hérite, en y ajoutant les traitements dont elle a
besoin. Dans notre exemple, la méthode recueille un identificateur handle pointant sur l'objet PrintWriter, ce qui lui permet de se servir de cet
objet pour envoyer un document HTML vers le flux de sortie. A chaque
ligne commençant par out.println(, du contenu HTML est envoyé dans le
flux de sortie. La servlet retransmet ces données vers le navigateur, et
la page Web apparaît.
Les servlets et les pages JSP résultantes
Une page JSP correspond à une servlet prêt à être exécutée. Lorsque le
navigateur réclame une servlet et non une page JSP (c'était le cas pour
SalutMonde.java), le conteneur de servlets réceptionne la requête et la
transmet à la servlet qui a d'abord été compilée. Dans le cas d'une page
JSP, il n'est plus nécessaire de compiler le code source ; le simple fait de
la demander force le conteneur JSP Tomcat à compiler la page à la volée.
Dans le prochain exemple, nous allons voir ce qui se passe avec une page
JSP.
Commencez par saisir (ou récupérez dans le sous-répertoire
sources\jsc_03 du CD) le programme SalutMonde.jsp et stockez le fichier
dans le sous-répertoire <Tomcat>\webapps\ROOT. Cette page élémentaire
insère la chaîne "Salut à tout le monde" dans une expression à afficher.
<%-- Fichier SalutMonde.jsp --%>
<html>
<head>
<title>Premier source en JSP</title>
</head>
<body>
<h2><%= "Salut à tout le monde" %></h2>
</body>
</html>
Tomcat étant activé, ouvrez votre navigateur et saisissez l'adresse
suivante :
Session 3 - Introduction aux servlets
37
http://localhost:8080/SalutMonde.jsp
Patientez quelques secondes avant de voir apparaître la page. Ce délai
est dû au fait que Tomcat a constaté qu'il ne disposait pas d'une version
compilée de la page JSP. Il a donc d'abord créé un fichier source Java à
partir du fichier JSP, puis il a compilé ce fichier .java pour obtenir un
fichier .class exécutable. C'est le fichier compilé qui a généré le code
HTML qui a été renvoyé au navigateur. Lors de vos prochaines visites de
la même page, l'accès est quasi instantané.
Tomcat stocke les deux fichiers qu'il génère quelque part dans la sousstructure de répertoires <Tomcat>\work. Pour vérifier la présence des
deux fichiers, utilisez l'Explorateur pour aller jusqu'à ce répertoire work.
Cherchez le sous-répertoire localhost_8080 (ce qui correspond à l'adresse
de la racine ROOT du serveur). Vous devriez trouver deux fichiers portant
un nom assez long, mais basé sur celui du fichier .jsp (contenant SalutMonde quelque part). Le fichier .java est le code source Java et le fichier
.class est le fichier exécutable. Le Listing 3-2 montre le contenu du fichier .java. La partie imprimée en gras correspond à la partie générant
le code HTML.
Listing 3-2
Le code source SalutMonde.jsp produit ce code source Java
(_0002fSalutMonde_0002ejspSalutMonde_jsp_0.java).
import
import
import
import
import
import
import
import
import
import
import
import
javax.servlet.*;
javax.servlet.http.*;
javax.servlet.jsp.*;
javax.servlet.jsp.tagext.*;
java.io.PrintWriter;
java.io.IOException;
java.io.FileInputStream;
java.io.ObjectInputStream;
java.util.Vector;
org.apache.jasper.runtime.*;
java.beans.*;
org.apache.jasper.JasperException;
public class _0002fSalutMonde_0002ejspSalutMonde_jsp_0 extends HttpJspBase {
static {
38
JSP Web Training
Listing 3-2
Le code source SalutMonde.jsp produit ce code source Java
(_0002fSalutMonde_0002ejspSalutMonde_jsp_0.java). (...)
}
public _0002fSalutMonde_0002ejspSalutMonde_jsp_0( ) {
}
private static boolean _jspx_inited = false;
public final void _jspx_init() throws JasperException {
}
public void _jspService(HttpServletRequest request, HttpServletResponse
response)
throws IOException, ServletException {
JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
String _value = null;
try {
if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=8859_1");
pageContext = _jspxFactory.getPageContext(this, request, response,
"", true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// HTML // begin
[file="C:\\jakarta\\webapps\\ROOT\\SalutMonde.jsp";from=(0,24);to=(7,7)]
out.write("\r\n\r\n<html>\r\n <head>\r\n <title>Premier source
en JSP</title>\r\n </head>\r\n <body>\r\n <H2>");
// end
Session 3 - Introduction aux servlets
39
Listing 3-2
Le code source SalutMonde.jsp produit ce code source Java
(_0002fSalutMonde_0002ejspSalutMonde_jsp_0.java). (...)
// begin
[file="C:\\jakarta\\webapps\\ROOT\\SalutMonde.jsp";from=(7,10);to=(7,35)]
out.print( "Salut à tout le monde" );
// end
// HTML // begin
[file="C:\\jakarta\\webapps\\ROOT\\SalutMonde.jsp";from=(7,37);to=(10,0)]
out.write("</H2>\r\n </body>\r\n</html>\r\n");
// end
} catch (Exception ex) {
if (out.getBufferSize() != 0)
out.clearBuffer();
pageContext.handlePageException(ex);
} finally {
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
}
}
Cet exemple montre bien le formidable avantage de JSP. En effet, Tomcat
génère la totalité du code Java de la servlet, soit plus de soixante-dix
lignes, à partir d'un code source JSP de moins de dix lignes.
Si vous effectuez des modifications de votre fichier .jsp et
ne voyez pas les modifications prises en compte, arrêtez
et redémarrez Tomcat.
RÉVISION
●
La technologie des servlets constitue le soubassement de celle de
JSP.
●
Un conteneur de servlets sert à gérer le cycle de vie des servlets.
●
Les servlets multithread savent gérer plusieurs requêtes en parallèle.
40
JSP Web Training
●
Les servlets se basant sur l'interface SingleThreadModel traitent
les requêtes l'une après l'autre.
●
La méthode doGet() prend en charge le traitement des requêtes
HTTP et le renvoi des réponses HTTP.
●
Le conteneur JSP compile un fichier de page JSP en servlet .class
via l'étape intermédiaire du fichier .java.
TESTEZ VOS CONNAISSANCES
1. Qu'est-ce qu'une requête HTTP ?
2. Quel est l'usage de l'interface SingleThreadModel ?
3. Quels objets sont transmis en paramètres de la méthode init() de la
servlet ?
4. Quelle méthode sert à supprimer une servlet devenue inutile de la
mémoire ?
5. Quels paquetages doit-on importer pour supporter les servlets ?
Téléchargement