Cours Web Servlet 7. Servlet 7. Servlet 7. Servlet

publicité
7. Servlet
Servlet
Cours Web
Programme Java s'exécutant côté serveur Web
servlet
JSP
Servlet
prog. "autonome" stockés dans un fichier .class sur le serveur
prog. source Java embarqué dans une page .html
côté client
côté serveur
.class autonome
applet
servlet
embarqué dans .html
JavaScript
JSP
Lionel Seinturier
Université Pierre & Marie Curie
Servlet et JSP
[email protected]
11/7/02
Web
165
Lionel Seinturier
• exécutable avec tous les serveurs Web (Apache, IIS, ...)
• auxquels on a ajouté un "moteur" de servlet/JSP (le plus connu : Tomcat)
• JSP compilées automatiquement en servlet par le moteur
Web
166
7. Servlet
Lionel Seinturier
7. Servlet
Servlet
Illustration du fonctionnement des servlets
Principe
• les fichiers de bytecode (.class) sont stockés sur le serveur (comme des docs)
• par convention dans le répertoire servlet/
• ils sont désignés par une URL
http://www.lip6.fr/servlet/Prog
• le chargement de l'URL provoque l'exécution de la servlet
1
Client
Explorer
Netscape
...
Web
4
Serveur Tom
cat
IIS
Apache
JVM
...
167
2
Prog.class
3
clic
servlet
Sun
Microsoft
Lionel Seinturier
Web
168
Lionel Seinturier
7. Servlet
7. Servlet
Mécanismes mis en œuvre
Développement
• écriture d'une servlet = écriture d'une classe Java
Utilisation des packages Java javax.servlet.* et javax.servlet.http.*
• lors du premier chargement d'une servlet (ou après modification), le moteur
- instancie la servlet
! servlet = objet Java présent dans le moteur
• extension de la classe javax.servlet.http.HttpServlet
• redéfinition de la méthode service de cette classe
• définit le code à exécuter lorsque la servlet est invoquée
• elle est appelée automatiquement par le "moteur" de servlet
• puis, ou lors des chargements suivants, le moteur
- exécute le code dans un thread
void service( ServletRequest request , ServletResponse response );
! le code produit un résultat qui est envoyé au client
! en cas d'erreur dans le code Java de la servlet
message récupéré dans le navigateur
Web
169
représente la requête
envoyée par le client
! renseigné automatiquement
par le "moteur"
Lionel Seinturier
Web
représente la réponse
retournée par la servlet
! à renseigner dans
le code de la servlet
170
7. Servlet
Lionel Seinturier
7. Servlet
Aperçu de l'API servlet
Exemple de servlet
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
Méthodes appelables sur un objet request
- String getParameter(String param)
retourne la valeur du champ param transmis
dans les données du formulaire
imposé
public class HelloServlet extends HttpServlet {
- java.util.Enumeration getParameterNames()
public void service( ServletRequest request,
ServletResponse response )
retourne l'ensemble des noms de paramètres transmis à la servlet
- String getMethod()
throws ServletException, IOException
retourne la méthode HTTP (GET ou POST) utilisée pour invoquer la servlet
imposé par l'API servlet
{
Méthodes appelables sur un objet response
response.setContentType( "text/html" );
- void setContentType(String type)
ce qui suit est en HTML
définit le type MIME du document retourné par la servlet
PrintWriter out = response.getWriter();
- PrintWriter getWriter()
retourne un flux de sortie permettant à la servlet de produire son résultat
la servlet "print" le code HTML sur ce flux de sortie
Web
171
Lionel Seinturier
Web
172
récupère un flux pour
générer le résultat
Lionel Seinturier
7. Servlet
7. Servlet
Exemple de servlet (suite)
Exemple de servlet (code complet)
out.println( "<html><body>" );
out.println( "<h1>Hello depuis une servlet</h1>" );
out.println( "</body></html>" );
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloServlet extends HttpServlet {
} }
génération du
code HTML
public void service( ServletRequest request,
ServletResponse response )
throws ServletException, IOException {
Compilation
! HelloServlet.class installé
dans l'arborescence de Tomcat
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<html><body>" );
out.println( "<h1>Hello depuis une servlet</h1>" );
out.println( "</body></html>" );
Chargement via une URL de type
http://.../servlet/HelloServlet
! exécution de HelloServlet.class
Web
} }
173
Lionel Seinturier
Web
174
7. Servlet
Lionel Seinturier
7. Servlet
Deuxième exemple de servlet
Deuxième exemple de servlet
Chaque servlet n'est instanciée 1 seule fois
! persistance de ces données entre 2 invocations
Chaque servlet n'est instanciée 1 seule fois
! persistance de ces données entre 2 invocations
public class CompteurServlet extends HttpServlet {
int compteur = 0;
1ère invocation
public void service( ServletRequest request,
ServletResponse response )
throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
2ème invocation
out.println( "<html><body>" );
out.println( "<h1> "+ compteur++ + "</h1>" );
out.println( "</body></html>" );
} }
Web
175
Lionel Seinturier
Web
176
Lionel Seinturier
7. Servlet
7. Servlet
Récupération des données d'un formulaire
Récupération des données d'un formulaire
Méthode String
public class CompteurServlet extends HttpServlet {
getParameter(String)
d'un objet request
! retourne le texte saisi
! ou null si le nom de paramètre n'existe pas
public void service( ServletRequest request,
ServletResponse response )
throws ServletException, IOException {
<HTML> <BODY>
<FORM ACTION="http://..."
METHOD=POST>
Nom <INPUT NAME="nom"> <P>
Prénom <INPUT NAME="prenom"> <P>
<INPUT TYPE=SUBMIT VALUE="Envoi">
<INPUT TYPE=RESET
VALUE="Remise à zéro">
</FORM>
</BODY> </HTML>
Web
177
Lionel Seinturier
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
String nom = request.getParameter( "nom" );
String prenom = request.getParameter( "prenom" );
out.println(
out.println(
out.println(
out.println(
"<html><body>" );
"<h1>Exemple de résultat</h1>" );
"Bonjour " + prenom + " " + nom );
"</body></html>" );
} }
Web
178
7. Servlet
Lionel Seinturier
7. Servlet
Récupération des données d'un formulaire
Cycle de vie d'une servlet
GenericServlet
- void init(ServletConfig conf)
init()
destroy()
...
méthode appelée par le moteur au démarrage de la servlet
! peut être utilisée pour initialiser la servlet
! propager l'initialisation par super.init(conf)
! ne jamais utiliser de constructeur
HttpServlet
- void destroy()
service()
doGet()
doPut()
...
lorsque l'on veut détruire la servlet
Différenciation des méthodes HTTP
clic
Web
• service() traite toutes les requêtes HTTP
• doGet() doHead() doPost() doPut() doDelete() doTrace() MyServlet
peuvent être redéfinies pour traiter chaque requête HTTP
...
de façon différenciée
servlet
179
Lionel Seinturier
Web
180
Lionel Seinturier
7. Servlet
7. Servlet
Chaînage des servlets
Compléments sur l'API
servlet 4
• aggrégation des résultats fournis
par plusieurs servlets
! meilleure modularité
! meilleure réutilisation
Méthodes appelables sur un objet request
servlet 1
servlet 5
servlet
- String getProtocol()
retourne le protocole implanté par le serveur
servlet 2
(ex. : HTTP/1.1)
- String getServerName() / String getServerPort()
retourne le nom/port de la machine serveur
servlet 3
Utilisation d'un RequestDispatcher
• obtenu via un objet request
- String getRemoteAddr() / String getRemoteHost()
retourne l'adresse/nom de la machine cliente (ayant invoqué la servlet)
RequestDispatcher rd = request.getRequestDispatcher( "servlet1" );
- String getScheme()
Inclusion du résultat d'une autre servlet
- java.io.BufferedReader getReader()
retourne le protocole utilisé (ex. : http ou https) par le client
rd.include(request, response);
retourne un flux d'entrée permettant à une servlet chainée
de récupérer le résultat produit par la servlet précédente
! permet à la servlet chaînée de modifier le résultat
URL
Délégation du traitement à une autre servlet
rd.forward(request, response);
Web
181
Lionel Seinturier
Web
182
7. Servlet
Lionel Seinturier
7. Servlet
Gestion de la concurrence
Cookies
Par défaut les servlets sont exécutées de façon multi-threadée
Permettent à un serveur Web de stocker de l'information chez un client
Si une servlet doit être exécutée en exclusion mutuelle
(ex. : accès à des ressources partagées critiques)
implantation de l'interface marqueur SingleThreadModel
! moyen pour savoir "par où passe" un client, quand, en venant d'où, ...
! débat éthique ??
! l'utilisateur a la possibilité d'interdire leur dépôt dans son navigateur
public class CompteurServlet
extends HttpServlet
implements SingleThreadModel {
• définis dans la classe javax.servlet.http.Cookie
• on les crée en donnant un nom (String) et une valeur (String)
public void service( ServletRequest request,
ServletResponse response )
throws ServletException, IOException {
/** Du code en exclusion mutuelle avec lui-même */
}
}
• on les positionne via un objet response
Autre solution : définir du code synchronized dans la servlet
Quelques méthodes :
Web
183
Cookie uneCookie = new Cookie( "sonNom", "saValeur" );
response.addCookie( uneCookie );
• on les récupère via un objet request
Cookie[] desCookies = request.getCookies();
Lionel Seinturier
Web
String getName() / String getValue()
184
Lionel Seinturier
7. Servlet
7. Servlet
Suivi de session
Suivi de session
• HTTP protocole non connecté
• pour le serveur, 2 requêtes successives d'un même client sont indépendantes
Objectif : être capable de "suivre" l'activité du client sur +sieurs pages
Méthodes appelables sur un objet de type HttpSession
- void setAttribute( String name, Object value )
ajoute un couple (name, value) pour cette session
- Object getAttribute( String name )
retourne l'objet associé à la clé name ou null
Notion de session
! les requêtes provenant d'un utilisateur sont associées à une même session
! les sessions ne sont pas éternelles, elles expirent au bout d'un délai fixé
- void removeAttribute( String name )
enlève le couple de clé name
- java.util.Enumeration getAttributeNames()
retourne tous les noms d'attributs associés à la session
Sur un objet request
- void setMaxIntervalTime( int seconds )
spécifie la durée de vie maximum d'une session
- HttpSession session = request.getSession(true)
retourne la session courante pour cet utilisateur ou une nouvelle session
- long getCreationTime() / long getLastAccessedTime()
retourne la date de création / de dernier accès de la session
en ms depuis le 1/1/1970, 00h00 GMT → new Date(long)
- HttpSession session = request.getSession(false)
retourne la session courante pour cet utilisateur ou null
Web
185
Lionel Seinturier
Web
7. Servlet
186
Lionel Seinturier
7. Servlet
Partage de données entre servlets
Conclusion
Notion de contexte d'exécution
= ensemble de couples (name, value) partagées par toutes les servlets instanciées
Permettent d'étendre le comportement des serveurs Web avec des prog. Java
ServletContext ctx = getServletContext()
(héritée de GenericServlet)
Résumé des fonctionnalités
+ portabilité, facilité d'écriture (Java)
+ gestion des applications requièrant un suivi entre plusieurs programmes
(persistance des données dans les servlets)
Méthodes appelables sur un objet de type ServletContext
- void setAttribute( String name, Object value )
ajoute un couple (name, value) dans le contexte
+ servlet chargée et instanciée une seule fois
+ servlet exécutée avec des processus légers (threads)
- Object getAttribute( String name )
retourne l'objet associé à la clé name ou null
- void removeAttribute( String name )
enlève le couple de clé name
- java.util.Enumeration getAttributeNames()
retourne tous les noms d'attributs associés au contexte
Web
187
Lionel Seinturier
Web
188
Lionel Seinturier
Téléchargement