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