Technologie servlet Jean-Jacques LE COZ
J2EE Web Container JSP Page Servlet J ava 2 Standard Edition APIs EJB Container EJB JDBCJMS JNDI JTA JavaMail JAF RMI-IIOP JSF
Architecture trois niveaux sources de données SGBDR Serveur d'applications client navigateur Autres applications Internet Java côté serveur
Qu'est-ce qu'une servlet ? C'est une classe Java Exécutée en réponse à une requête HTTP Génère une réponse HTTP valide Non orthogonale vis à vis du service HTTP La servlet doit spécialiser HttpServlet A pour ancêtre la classe GenericServlet Possède une gestion d'exception spécifique
Exemple de servlet import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class BonjourLeMonde extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType(''text/html''); PrintWriter out = res.getWriter(); out.println(''Bonjour Le Monde''); out.close(); }
Exemple de descripteur <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" " NomLogique NomDuFichier.class NomLogique /cheminInvocation/NomInvocation
Packages javax.servlet.*
Exécution d'une servlet Dans un environnement géré Serveur d'applications Offre de services Sécurité, pool de connexions, cluster, etc. Deux modes d'exécution Mode multi-threading Mode mono-threading
Environnement géré Machine virtuelle Java (JVM) ServeurServices composants Web (servlet, JSP, HTML, XML ) JavaBean, POJO
Méthodes héritées (1) De la classe GenericServlet Méthode init() Exécutée au chargement de la servlet Méthode init(ServletConfig) Exécutée au chargement de la servlet Méthode service() Exécutée à chaque réception de requête Elle délègue le traitement à la méthode demandée Méthode destroy() Exécutée au déchargement de la servlet
Méthodes héritées (2) De la classe HttpServlet Invocation en réponse aux requêtes HTTP Méthodes d'implémentation du protocole HTTP Méthode doPost() Invoquée pour modifier l'état d'une ressource Méthode doGet() Invoquée pour récupérer de l'information
Méthodes héritées (3) De la classe HttpServlet Méthodes d'implémentation du protocole HTTP Méthode doHead() Retourne les entêtes Méthode doDelete() Supprime les ressources Méthode doPut() Stocke une ressource Méthode doTrace() Retourne une réponse avec tous les headers Méthode doOption() Détermine les méthodes HTTP supportées
La méthode service() Elle délègue le traitement de la requête à la méthode invoquée par la requête HTTP requête HTTP service() doGet() doPost() do...() réponse HTTP
Déploiement d'une servlet Préférable de déployer sous une forme typique de fichier JAR. Fichiers WAR (Web App Repository). A partir de la version 2.2 des spécifications. Contiennent les règles de déploiement : Correspondance entre URIs (Uniform Resource Identifiers) et les ressources. Permet de déployer une application avec un seul fichier “binaire” sans les sources.
Standardisation du déploiement Archive war standardisée Le descripteur de déploiement web.xml standardisé Structure d'accueil des déploiements côté serveurs d'application lui aussi standardisé Répertoire webapps Portabilité
Structure de l'archive WAR Répertoire de l'application Répertoires de confort Images, vidéo, audio,... Répertoire WEB-INF Fichier descripteur de déploiement web.xml Fichier descripteur de contexte Répertoire classes Contient l'application (paquetages et classes Java) Répertoire lib Contient les librairies jar nécessaires à l'application
Arborescence de l'archive application imagespagesWEB-INF classeslib paquetageslibrairies
Servlet : cycle de vie
Cycle de vie général
Chargement multi-threads serveur d'applications instance requête Thread
Comportement multi-threads Attention aux interactions entre threads Les variables locales aux méthodes ne peuvent pas être corrompues Contexte différent Les variables d'instance peuvent être corrompues Solution Synchroniser le code qui pose problème au sein des méthodes
Connexions et multi-threads Pool de connexions JDBC Pour palier à l'accroissement des connexions Autant de threads que de connexions ? De nombreux pool disponibles Logiciels libres Jakarta-Commons Database Connection Pool
Intérêts du multi-threads Performance Empreinte mémoire réduite Pas de surcoût de création d'objet Facilité Persistance des threads créées par les servlets Ressources persistantes Connexions (JNDI, JDBC,...)
Chargement mono-thread serveur d'applications pool de servlets requête Thread instance
Modèle mono-thread Modèle non conseillé par les éditeurs et les experts Implémentation Interface javax.servlet.singleThreadModel Sûr vis à vis des threads Pas besoin de synchroniser les méthodes Connexions concurrentes à un SGBD Pas besoin d'un pool de connexions
Observateurs du cycle de vie Depuis la version Servlet 2.3 Système événementiel API pour observer les événements Cycle de vie Chargement (création) Déchargement (destruction) Modification d'attributs Du contexte (ServletContext) De la session (HttpSession)
Notion de Event Listener Implémentation de méthodes Notification lors d'un événement Event Listener Possibilité de définir plusieurs Listener Possibilité de définir l'ordre d'invocation C'est le serveur d'applications qui a la responsabilité de gérer le cycle de vie des Listeners
Interfaces de l'API (1) Paquetage javax.Servlet.* ServletContextListener Observe le cycle de vie de la servlet ServletContextAttributesListener Observe l'ajout, la suppression et la modification des attributs du contexte de la servlet
Interfaces de l'API (2) Paquetage javax.Servlet.http.* HttpSessionListener Observe le cycle de vie de la session SessionAttributesListener Observe l'ajout, la suppression et la modification des attributs de la session
Exemple d'implémentation package monpackage; import javax.servlet.ServletContext; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributesListener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public final class MonContextListener implements ServletContextListener { private ServletContext context = null; public MonContextListener() {} public void contextDestroyed(ServletContextEvent event) { System.out.println("Application déchargée"); this.context = null; } public void contextInitialized(ServletContextEvent event) { this.context = event.getServletContext(); System.out.println("Application chargée"); }
Pièges du cycle de vie Les traitements en arrière plan Les servlets persistent entre les requêtes Les servlets travaillent entre les requêtes Attention aux threads démarrées dans la méthode init() Les threads sont arrêtées par la méthode destroy()
Retrouver l'information
Informations envoyées par le client Récupération grâce à l'objet requête HttpServletRequest Invocation des méthodes sur l'objet requête String getParameter(String nom) ; String[ ] getParameterValues(String nom) ; Si les paramètres proviennent d'une requête de type POST Ils ne peuvent être lus qu'une seule fois
Gestion de formulaire nom : Dupont serveur POST public class MaServlet extends HttpServlet { public void doPost(.... ) { String param = req.getParameter(''nom'') ;... OK Navigateur
Exemple de formulaire Formulaire <FORM METHOD=POST ACTION=''
Exemple de récupération import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class GestDonnees extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType(''text/html'') ; PrintWriter out = res.getWriter() ; String nom = req.getParameter(''nom'') ;... out.println( ''Bonjour ''+nom) ;... }
Informations complémentaires Obtenir le chemin logique Hostname et URL getRequestURL() URI getRequestURI() Informations composant le chemin logique getServerName(), getServerPort() getContextPath(), getServletPath() getPathInfo()
Informations complémentaires Obtenir le libellé de la requête getQueryString() Obtenir le chemin physique getPathTranslated() Obtenir le type MIME getMimeType(String file)
Différents contextes (1) Informations de contexte Portées de contexte Application Requête Session Page Permet de stocker, supprimer et retrouver des informations Partagées par tous les composants Le cycle de vie des informations dépend de la portée du contexte
contexte Informations de contexte portée application portée requête portée page portée session JSP POJO SERVLET LIRE/ECRIRE
Différents contextes (2) Paramètres de contexte Portées de contexte Application Servlet Disponibles à tout moment Pour définir Des valeurs par défaut Des valeurs initiales Permet de personnaliser le comportement De l'application D'une servlet
Informations de contexte Gestion du contexte Avec l'objet ServletContext Implémentation du Pattern Singleton Grâce aux méthodes setAttribute(), getAttribute(), removeAttribute() getAttributeNames()
Paramètres de contexte (1) Récupération grâce à l'objet ServletContext Contexte de l'application Partagé par tous les composants Informations stockées dans le fichier web.xml Section Grâce aux méthodes getInitParameter(String nom) getInitParameterNames()
Paramètres de l'application url jdbc://localhost/mabase... FICHIER WEB.XML JSP SERVLET POJO getInitParameter
Paramètres de contexte (2) Récupération grâce à l'objet ServletContext Contexte de la servlet Attaché à une instance de servlet Informations stockées dans le fichier web.xml Section Grâce aux méthodes getInitParameter(String nom) getInitParameterNames()
Paramètres d'une servlet url jdbc://localhost/mabase... FICHIER WEB.XML SERVLET getInitParameter
Exemple public void init(ServletConfig config) throws ServletException { super.init(config) ; String param = getInitParameter(''nomParametre'');
Informations distantes (1) Obtenir le nom de l'utilisateur getRemoteUser() Obtenir le type d'autorisation getAuthType() Obtenir l'adresse du poste client getRemoteAddr() Obtenir le nom du poste client getRemoteHost()
Informations distantes (2) Comment sont obtenues les informations Grâce à la socket qui connecte le client au serveur Convertion de chaîne de caractères en adresse TCP/IP Type InetAddress InetAddress adresse = InetAdress.getByName(req.getRemoteAddress())
Informations locales Informations sur le serveur du contexte Grâce à l'objet ServletContext getServerInfo() getServerName() Grâce à l'objet ServletRequest getServerPort() Informations locales à l'application Récupération du chemin physique de l'application getRealPath()
Informations de session (1) Problème de persistance des informations liées à une session utilisateur Le protocole HTTP est sans état (stateless) Impossibilité de mémoriser les actions passées Intolérable dans un contexte B2B ou B2C Dépassement du problème avec HttpSession Gestion déléguée au serveur Au dessus des solutions classiques CGI Champs de formulaire cachés Réécriture d'URL Utilisation de cookies
Informations de session (2) L'objet HttpSession Permet à l'information de persister tout au long d'une session utilisateur Se comporte comme une Map Permet de mémoriser les types primitifs Java et les types construits Les objets doivent être serializables Méthodes getSession(), setAttribute(), getAttribute() invalidate()
Retourner de l'information
Typer l'information Pour prévenir le client Permet au client de prévoir les applications susceptibles de l'aider à présenter l'information Méthode setContentType() Permet de préciser le type MIME Type MIME Multipurpose Internet Mail Extensions text/html, text/XML,...
Flux d'information Informations binaires Objet ServletOutputStream Récupérer par getOutputStream() Informations caractères Objet PrintWriter Récupérer par getWriter()
Exemple text/html public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType(''text/html'') ; PrintWriter out = res.getWriter() ; out.println( ''Bonjour Le Monde'') ; out.close(); }
Exemple text/xml public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType(''text/xml''; charset=UTF-8") ; PrintWriter out = res.getWriter() ; out.println(" "); out.print ("<?xml-stylesheet "); out.println("type='text/css' href='/xml/styles/mes.css'?>"); out.println(" "); out.println("ISDRN''); out.println(" "); out.close(); }
Déléguer le retour d'information Délégation A une autre servlet A une page JSP Grâce à l'objet ServletContext Méthodes getRequestDispatcher() forward()
Inclure l'information d'un autre composant Inclusion Le flux de sortie d'une autre servlet Le flux de sortie d'une JSP Grâce à l'objet ServletContext Méthodes getRequestDispatcher() include()
Délégation et inclusion serveur ServletA ServletB ServletC requête réponse JSP délégation par forward inclusion par include
Exemple forward public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { RequestDispatcher dispatcher = request.getRequestDispatcher(''/AutreServlet''); dispatcher.forward(req, res); }
Filtrer l'information
Les servlets de type filtre Filtrer pourquoi faire ? Gestion des droits d'accès Contrôle de saisie Changement d'apparence Utilisation de types spéciaux Supporter des types de données ésotériques
Chaînage de filtres serveur FiltreA FiltreB Servlet FiltreC requête réponse amont aval
Implémentation des filtres Paquetages javax.servlet.Filter javax.servlet.FilterChain javax.servlet.FilterConfig Service de filtrage Par implémentation de l'interface Filter Méthodes init() destroy() dofilter()
Descripteur de filtre Fichier web.xml Les filtres sont contrôlés par le serveur
Serveurs d'applications Synonymes Moteur de servlet Conteneur Serveur Web Serveurs du marché Tomcat (consortium apache) Jetty (communauté Mort Bay) Resin (communauté caucho) WebSphere (IBM) WebLogic (BEA)
Conclusion Applications web : maillon important des systèmes d'information Les servlets excellent dans la création d'informations En réponse à des requêtes HTTP A partir de document XML A partir de bases de données Les servlets tirent avantage de Java Portabilité, puissance, efficacité, sécurité, intégration, modularité, réutilisation
Bibliographie Livres Java Servlets Jason Hunter O'REILLY Java Servlet Programming Jason Hunter O'REILLY Professional Java Servlets 2.3 Andrew Harbourne Paperback Sites web java.sun.com (J2EE tutorial) jguru.com