Vous êtes sur la page 1sur 74

INSA - ASI

TechnoWeb : Servlet

1/74

Technologie Web
Les Servlets Alexandre Pauchet
INSA Rouen - Dpartement ASI
BO.B.RC.18, pauchet@insa-rouen.fr

INSA - ASI

TechnoWeb : Servlet

2/74

Plan

Introduction
6

Filtrage Partage du contrle Sessions

API
7

Encodage
8

Paramtres Servlets et Threads

INSA - ASI

TechnoWeb : Servlet

3/74

Introduction
Description

(1/9)

Que sont les Servlets ? Applications java Excutes ct serveur Traitement de requtes HTTP et gnration de rponses dynamiques comparables aux CGI Permettent dtendre les fonctionnalits de base dun serveur HTTP Quelques avantages :
Portabilit (java) Puissance avec laccs la totalit de lAPI java Rapidit (la Servlet est charge une seule fois)

INSA - ASI

TechnoWeb : Servlet

4/74

Introduction

(2/9)

Fonctionnement des CGI

INSA - ASI

TechnoWeb : Servlet

5/74

Introduction

(3/9)

Fonctionnement des Servlets

INSA - ASI

TechnoWeb : Servlet

6/74

Introduction
Application Web

(4/9)

Une application web J2EE est compose


De Servlets/JSP De bibliothques de classes annexes, De ressources statiques (images, HTML, XHTML, . . . ), Un descripteur de dploiement (chier XML)

INSA - ASI

TechnoWeb : Servlet

7/74

Introduction
Application J2EE

(5/9)

Serveur dapplication J2EE


Une application J2EE est compose dune partie Web et dun ensemble dEJB

Conteneur web

Conteneur EJB

Serveur dapplications

Exemple de serveur web J2EE : Tomcat Exemple de serveur dapplications J2EE : JBoss

INSA - ASI

TechnoWeb : Servlet

8/74

Introduction
Vocabulaire J2EE

(6/9)

J2EE et les applications Web Composant Web : Servlets et JSP Application Web : ensemble de composants web, bibliothques et ressources statiques dont lorganisation est dcrite dans un descripteur de dploiement Conteneur Web :
Environnement dexcution et de distribution des composants web et des ressources statiques Gre le cycle de vie des Servlets (intanciation, initialisation, . . . )

INSA - ASI

TechnoWeb : Servlet

9/74

Introduction

(7/9)

Exemple de Servlet : la Servlet

Hello.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Hello extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/plain"); PrintWriter out = reponse.getWriter(); out.println("Hello, hello !!!!"); } }

INSA - ASI

TechnoWeb : Servlet

10/74

Introduction

(8/9)

Exemple de Servlet : le chier appelant

Hello.html
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> < title >Ma premire Servlet</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <meta http-equiv="REFRESH" content="0;http://localhost:8080/Hello/Servlet/Coucou"> </head> <body> </body> </html>

Remarque
Certaines versions de tomcat/jboss ne supportent pas lextension .xhtml

INSA - ASI

TechnoWeb : Servlet

11/74

Introduction
web.xml

(9/9)

Exemple de Servlet : le chier de dploiement

<?xml version="1.0" encoding="ISO-8859-1"?> <!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>Bonjour</servlet-name> <servlet-class>Hello</servlet-class> </servlet> <servlet-mapping> <servlet-name>Bonjour</servlet-name> <url-pattern>/Servlet/Coucou</url-pattern> </servlet-mapping> </web-app>

Appel sur JBOSS


Dpt de larchive Hello.war dans $JBOSS_HOME/server/default/deploy/ Appel : http://localhost:8080/Hello/Servlet/Coucou Ici la Servlet ne supporte que le GET

INSA - ASI

TechnoWeb : Servlet

12/74

API

(1/6)

Application Web

Arborescence dune archive WAR (Web ARchive)


ApplicationWeb.war |_ fichiers.html |_ fichiers.jsp |_ rpertoires/fichiers |_ META-INF | |_ MANIFEST.MF |_ WEB-INF |_ web.xml |_ classes |_ Servlets.class |_ lib |_ bibliotheques.jar

INSA - ASI

TechnoWeb : Servlet

13/74

API

(2/6)

Compilation et dploiement

Compilation
La compilation de Servlets ncessite lajout de bibliothques JAR dans le classpath ; pour JBOSS, utilisation du script $JBOSS_HOME/bin/classpath.sh

Dploiement
Le rpertoire ApplicationWeb.war est plac dans le rpertoire dapplications du conteneur web
webapps pour Tomcat $JBOSS_HOME/server/JBOSS_MODE/deploy pour Jboss

Ou un chier ApplicationWeb.war (chier archive web) ayant pour contenu ApplicationWeb :


cd ApplicationWeb ; jar cf ApplicationWeb.war *

INSA - ASI

TechnoWeb : Servlet

14/74

API

(3/6)

Descripteur de dploiement

Fichier web.xml
Le chier web.xml contient la description du dploiement. Il doit tre valide par rapport une DTD.
<?xml version="1.0" encoding="ISO-8859-1"?> <!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>Alias de la Servlet</Servlet-name> <servlet-class>Nom de la classe Servlet</Servlet-class> </servlet> <servlet-mapping> <servlet-name>Alias de la Servlet</Servlet-name> <url-pattern>chemin de lURL dclenchant le chargement de la Servlet</url-pattern> <!-- le joker * est autoris dans le chemin --> </servlet-mapping> </web-app>

Attention de bien respecter la DTD (ordre des tags)

INSA - ASI

TechnoWeb : Servlet

15/74

API

(4/6)

Cycle de vie

Gestion du cycle de vie des Servlets : Le conteneur Web doit se conformer la gestion des Servlets :
Cration et initialisation de Servlets Traitement des services demands par les ventuels clients Destruction des Servlets et libration de lespace mmoire (ramasse-miettes)

Java propose une API permettant de construire des Servlets :


LAPI permet au dveloppeur de grer la cration, les requtes et la destruction des Servlets Le conteneur fait appel cette API pour grer les Servlets

INSA - ASI

TechnoWeb : Servlet

16/74

API

(5/6)

API : classe GenericServlet

API J2EE SDK Ncessite linstallation du J2EE SDK Packages : javax.Servlet.* et javax.Servlet.http.* La classe GenericServlet :
public abtract class GenericServlet { GenericServlet() // mthodes grant linitialisation et la destruction void destroy() void init() void init(ServletConfig config) // mthodes pour la rcupration des paramtres passs String getInitParameter(String name) Enumeration getInitParameterNames() // rcupration dinformations concernant la Servlet ServletConfig getServletConfig() ServletContext getServletContext() String getServletInfo() String getServletName() // criture de logs, pratique pour le dbugage void log(String msg) void log(String message, Throwable t) // traite les requte (doit tre redfinie dans la sous-classe) abstract void service(ServletRequest req, ServletResponse res) }

INSA - ASI

TechnoWeb : Servlet

17/74

API

(6/6)

API : classe HttpServlet

Classe HttpServlet :
public abtract class HttpServlet extends GenericServlet { HttpServlet() // mthodes rpondant aux diffrents types de requtes protected void doDelete(HttpServletRequest req, HttpServletResponse resp) protected void doGet(HttpServletRequest req, HttpServletResponse resp) protected void doHead(HttpServletRequest req, HttpServletResponse resp) protected void doOptions(HttpServletRequest req, HttpServletResponse resp) protected void doPost(HttpServletRequest req, HttpServletResponse resp) protected void doPut(HttpServletRequest req, HttpServletResponse resp) protected void doTrace(HttpServletRequest req, HttpServletResponse resp) // permet dutiliser le cache ct client protected long getLastModified(HttpServletRequest req) // grent le dispatching en fontion du type de requte} protected void service(HttpServletRequest req, HttpServetResponse resp) protected void service(ServletRequest req, ServletResponse res) }

Classes utiliser pour crer ses propres Servlets


Driver HttpServlet comme support pour votre Servlet HttpServletRequest : toutes les donnes de la requte HttpServletResponse : rponse la requte

INSA - ASI

TechnoWeb : Servlet

18/74

Encodage

(1/4)

Gnration de texte accentu

Gestion de texte accentu


Requtes HTTP transmises aux Servlet :
doGet(ServletRequest req, ServletResponse rep) doPost(ServletRequest req, ServletResponse rep)

... Toutes les entres et sorties peuvent tre (re)traites : ServletRequest dnit la mthode void setCharacterEncoding(String env) ServletResponse dnit les mthodes
void setContentType(java.lang.String type) void setLocale(java.util.Locale loc)

INSA - ASI

TechnoWeb : Servlet

19/74

Encodage

(2/4)

Exemple de gnration de texte accentu

Encodage.java
import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.Locale;

public class Encodage extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/plain; charset=UTF-8"); reponse.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); PrintWriter out = reponse.getWriter(); out.println("Texte accentu : "); } }

INSA - ASI

TechnoWeb : Servlet

20/74

Encodage

(3/4)

Traitement de requtes contenant des accents

CodageGet.java
import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.Locale;

public class CodageGet extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/plain; charset=UTF-8"); reponse.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); PrintWriter out = reponse.getWriter(); String texte; requete.setCharacterEncoding("UTF-8"); texte = requete.getParameter("texte"); out.println("Texte aprs traitement : " + texte); } }

INSA - ASI

TechnoWeb : Servlet

21/74

Encodage

(4/4)

Traitement de requtes contenant des accents

codageGet.html
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> < title >Saisissez du texte avec accents</title> </head> <body> <h1>Bonjour</h1> <form action="/CodageGet/Servlet/CodageGet" method="get"> <label>Texte avec accent : </label><input type="text" name="texte" size="30"> <input type="submit" value="envoyer"> </form> </body> </html>

INSA - ASI

TechnoWeb : Servlet

22/74

Paramtres

(1/15)

Paramtres provenant des formulaires : principe

Rcupration de paramtres en provenance dun formulaire


Les paramtres de formulaires sont rcuprables via HttpServletRequest La rcupration se fait par les mthodes suivantes :
Enumeration getParameterNames() String getParameter(String name) String[] getParameterValues(String name) :

pour un champ de formulaire ayant plusieurs valeurs (liste choix multiples, cases cocher, etc.),

INSA - ASI

TechnoWeb : Servlet

23/74

Paramtres

(2/15)

Paramtres provenant des formulaires : exemple

HelloPost.html
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> < title >Ma premire Servlet</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Bonjour</h1> <form action="/HelloPost/Servlet/Coucou" method="POST"> <label>Prnom : </label><input type="text" name="prenom" size="30"> <input type="submit" value="envoyer"> </form> <hr/> <address><a href="mailto:Alexandre.Pauchet@insa-rouen.fr">Alexandre Pauchet</a></address> </body> </html>

INSA - ASI

TechnoWeb : Servlet

24/74

Paramtres

(3/15)

Paramtres provenant des formulaires : exemple

HelloPost.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloPost extends HttpServlet { public void doPost(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { String prenom = requete.getParameter("prenom"); reponse.setContentType("text/html"); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<body>"); out.println("<h1>Bonjour " + prenom + " ! </h1>"); out.println("<p>Ceci est ma premiere Servlet...</p>"); out.println("</body>"); out.println("</html>"); } }

INSA - ASI

TechnoWeb : Servlet

25/74

Paramtres
Passage en GET

(4/15)

HelloGet.html
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> < title >Ma premiere Servlet</title> </head> <body> <h1>Bonjour</h1> <form action="/HelloGet/Servlet/HelloGet" method="GET"> <label>Prenom : </label><input type="text" name="prenom" size="30"> <input type="submit" value="envoyer"> </form> <hr /> <address><a href="mailto:Alexandre.Pauchet@insa-rouen.fr">Alexandre Pauchet</a></address> </body> </html>

INSA - ASI

TechnoWeb : Servlet

26/74

Paramtres
Passage en GET

(5/15)

HelloGet.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloGet extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { String prenom = requete.getParameter("prenom"); reponse.setContentType("text/html"); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<body>"); out.println("<h1>Bonjour " + prenom + " ! </h1>"); out.println("<p>Ceci est ma premire Servlet...</p>"); out.println("</body>"); out.println("</html>"); } }

INSA - ASI

TechnoWeb : Servlet

27/74

Paramtres
web.xml

(6/15)

Paramtres dinitialisation

<?xml version="1.0" encoding="ISO-8859-1"?> <!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>ParamInit</servlet-name> <servlet-class>ParamInit</servlet-class> <init-param> <param-name>parametre1</param-name> <param-value>valeur1</param-value> <description>test de parametre</description> </init-param> <init-param> <param-name>parametre2</param-name> <param-value>valeur2</param-value> <description>test de parametre</description> </init-param> </servlet> <servlet-mapping> <servlet-name>ParamInit</servlet-name> <url-pattern>/Servlet/ParamInit</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

28/74

Paramtres

(7/15)

Paramtres dinitialisation

ParamInit.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ParamInit extends HttpServlet { String param1; String param2; public void init() { this .param1=getInitParameter("parametre1"); this .param2=getInitParameter("parametre2"); } public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/plain"); PrintWriter out= reponse.getWriter(); out.println("parametre1 = "+this.param1); out.println("parametre2 = "+this.param2); } }

INSA - ASI

TechnoWeb : Servlet

29/74

Paramtres

(8/15)

Paramtres de contexte : principe

Les paramtres de contexte


Association de paramtres un ensemble de Servlets : contrairement aux paramtres dinitialisation de Servlet prcdents, ceux-ci sont commun toutes les Servlets de lapplication web. Dclaration : dans web.xml
<web-app> <context-param> <param-name>parametrecontext</param-name> <param-value>valeurcontext</param-value> </context-param> <!-- dclaration des Servlets --> </web-app>

Rcupration dans la Servlet :


ServletContext context = getServletContext(); chainecontext = context.getInitParameter("parametrecontext");

INSA - ASI

TechnoWeb : Servlet

30/74

Paramtres

(9/15)

Paramtres de contexte : exemple

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!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> <context-param> <param-name>parametreDeContexte</param-name> <param-value>valeurContextuelle</param-value> <description>test de parametre</description> </context-param> <servlet> <servlet-name>ParamContext</servlet-name> <servlet-class>ParamContext</servlet-class> </servlet> <servlet-mapping> <servlet-name>ParamContext</servlet-name> <url-pattern>/Servlet/ParamContext</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

31/74

Paramtres

(10/15)

Paramtres de contexte : exemple

ParamContext.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ParamContext extends HttpServlet { String chainecontext; public void init() { ServletContext context = getServletContext(); chainecontext = context.getInitParameter("parametreDeContexte"); } public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/plain"); PrintWriter out = reponse.getWriter(); out.println("Parametre de contexte = "+chainecontext); } }

INSA - ASI

TechnoWeb : Servlet

32/74

Paramtres

(11/15)

Attributs de contexte : principe

Attributs de contexte
Partager des informations entre plusieurs Servlet :
le partage est eectu travers le contexte dexcution gr par ServletContext

Obtention du contexte dune Servlet :


ServletContext getServletContext(String uripath)

Manipulation dattributs du contexte par ServletContext :


void setAttribute(String name, Object o) Object getAttribute(String name) Enumeration getAttributeNames() void removeAttribute(String name)

INSA - ASI

TechnoWeb : Servlet

33/74

Paramtres
web.xml

(12/15)

Attributs de contexte : exemple

<?xml version="1.0" encoding="ISO-8859-1"?> <!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>Increment</servlet-name> <servlet-class>AttributContextIncrement</servlet-class> </servlet> <servlet> <servlet-name>Lecteur</servlet-name> <servlet-class>AttributContextLecteur</servlet-class> </servlet> <servlet-mapping> <servlet-name>Increment</servlet-name> <url-pattern>/Servlet/Increment</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Lecteur</servlet-name> <url-pattern>/Servlet/Lecteur</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

34/74

Paramtres

(13/15)

Attributs de contexte : exemple

AttributContextLecteur.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class AttributContextLecteur extends HttpServlet { ServletContext context; public void init() { context = getServletContext().getContext("/AttributContext"); if (context.getAttribute("compteur") == null) context.setAttribute("compteur","0"); } public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/html"); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<body>"); out.println("<h1> Lecteur valeur de compteur partage : "+context.getAttribute("compteur")+"</h1>"); out.println("<a href=/AttributContext/Servlet/Increment>incremente</a>"); out.println("<a href=/AttributContext/Servlet/Lecteur>lecteur</a>"); out.println("</form>"); out.println("</body>"); out.println("</html>"); } }

INSA - ASI

TechnoWeb : Servlet

35/74

Paramtres

(14/15)

Attributs de contexte : exemple

AttributContextIncrement.java
import import import import java.io.*; java.lang.*; javax.servlet.*; javax.servlet.http.*;

public class AttributContextIncrement extends HttpServlet { ServletContext context; public void init() { context = getServletContext().getContext("/AttributContext"); if (context.getAttribute("compteur") == null) context.setAttribute("compteur","0"); } public int incremente() { try { int compteur = Integer.parseInt(""+context.getAttribute("compteur"))+1; context.setAttribute("compteur",""+compteur); return compteur; } catch (NumberFormatException exception) { log("TestAttributContext1 : probleme de conversion en int"); log(""+exception); } return -1; }

INSA - ASI

TechnoWeb : Servlet

36/74

Paramtres

(15/15)

Attributs de contexte : exemple

AttributContextIncrement.java
public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/html"); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<body>"); out.println("<h1> Increment valeur de compteur partage : "+incremente()+"</h1>"); out.println("<a href=/AttributContext/Servlet/Increment>incremente</a>"); out.println("<a href=/AttributContext/Servlet/Lecteur>lecteur</a>"); out.println("</form>"); out.println("</body>"); out.println("</html>"); } }

INSA - ASI

TechnoWeb : Servlet

37/74

Servlets et Threads
Traitement des requtes

(1/9)

Remarque
Le conteneur WEB ne contient quUNE instance de chaque Servlet Les requtes sont traites dans des threads : persistance de la Servlet dune requte une autre, persistance des threads, taille mmoire rduite, pas de surcot pour traiter une nouvelle requte (dj charge), mmoire partage (exemple pratique : la connexion une BD est initialise au chargement), il faut grer les problmes de synchronisation (utilisation de lexclusion mutuelle).

INSA - ASI

TechnoWeb : Servlet

38/74

Servlets et Threads
Exemple : Compteur simple

(2/9)

CompteurSimple.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CompteurSimple extends HttpServlet { private int compteur = 0; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); compteur++; out.println("Compteur : "+compteur); } }

INSA - ASI

TechnoWeb : Servlet

39/74

Servlets et Threads
Exemple : Compteur simple

(3/9)

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!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>CompteurSimple</servlet-name> <servlet-class>CompteurSimple</servlet-class> </servlet> <servlet-mapping> <servlet-name>CompteurSimple</servlet-name> <url-pattern>/Servlet/CompteurSimple</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

40/74

Servlets et Threads

(4/9)

Exemple : Compteur avec synchronisation

CompteurSynchro1.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CompteurSynchro1 extends HttpServlet { private int compteur = 0; public synchronized void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // pb la servlet ne traite quune requete a la fois res.setContentType("text/plain"); PrintWriter out = res.getWriter(); compteur++; out.println("Compteur : "+compteur); } }

INSA - ASI

TechnoWeb : Servlet

41/74

Servlets et Threads

(5/9)

Exemple : Compteur avec synchronisation

CompteurSynchro2.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CompteurSynchro2 extends HttpServlet { private int compteur = 0; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // seule la partie necessitant lexclusion mutuelle est prise en compte res.setContentType("text/plain"); PrintWriter out = res.getWriter(); int valCompteur; synchronized(this) { valCompteur = ++compteur; } out.println("Compteur : "+valCompteur); } }

INSA - ASI

TechnoWeb : Servlet

42/74

Servlets et Threads

(6/9)

Exemple : Compteur dinstances de Servlet

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!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>CompteurA</servlet-name> <servlet-class>CompteurInstances</servlet-class> </servlet> <servlet> <servlet-name>CompteurB</servlet-name> <servlet-class>CompteurInstances</servlet-class> </servlet> <servlet-mapping> <servlet-name>CompteurA</servlet-name> <url-pattern>/Servlet/CompteurA</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CompteurB</servlet-name> <url-pattern>/Servlet/CompteurB</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

43/74

Servlets et Threads

(7/9)

Exemple : Compteur dinstances de Servlet

CompteurInstances.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CompteurInstances extends HttpServlet { private static int nbInstances = 0; private static int compteurClasse = 0; private int compteur = 0; public void init() throws ServletException { nbInstances++; } public void destroy() { nbInstances--; } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); compteur++; compteurClasse++; out.println("Compteur pour cette instance : "+compteur); out.println("Nombre dinstances de la servlet : "+nbInstances); out.println("Compteur totale sur lensemble des instances de la servlet : "+compteurClasse); } }

INSA - ASI

TechnoWeb : Servlet

44/74

Servlets et Threads

(8/9)

Exemple : Compteur persistant

CompteurPersistant.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CompteurPersistant extends HttpServlet { private int compteur = 0; public synchronized void init() throws ServletException { try { FileReader file = new FileReader("/tmp/compteur.txt"); BufferedReader reader = new BufferedReader(file); compteur = Integer.parseInt(reader.readLine()); reader.close(); } catch (FileNotFoundException exception) {} catch (IOException exception) {} catch (NumberFormatException exception) {} } public void destroy() { super.destroy(); enregistrerEtat(); }

INSA - ASI

TechnoWeb : Servlet

45/74

Servlets et Threads

(9/9)

Exemple : Compteur persistant

CompteurPersistant.java
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); compteur++; out.println("Compteur : "+compteur); if (compteur % 20 == 0) enregistrerEtat(); } public synchronized void enregistrerEtat() { try { FileWriter file = new FileWriter("/tmp/compteur.txt"); PrintWriter writer = new PrintWriter(file); writer.println(compteur); writer.close(); } catch (IOException exception) { log("ErreurServlet : enregistrement de letat impossible pour CompteurPersistant"); log(""+exception); } } }

INSA - ASI

TechnoWeb : Servlet

46/74

Filtrage

(1/7)

Principes du ltrage

Principes du ltrage
Application de ltres :
aux requtes faites aux servlets aux rponses de servlets

Objectif : modier leur entte et/ou leur contenu Utilisation :


authentication, conversion (ex : formats dimage), journalisation (ex : ajout dune date), transformations XML, ...

INSA - ASI

TechnoWeb : Servlet

47/74

Filtrage

(2/7)

Mise en uvre

Implmentation de linterface Filter


Trois mthodes rednir :
void init(FilterConfig) : permet de rcuprer des informations sur le ltre mais aussi sur la servlet via le context void destroy() : pour librer des ressources la destruction void doFilter(ServletRequest req, ServletResponse, FilterChain chain) : examiner la requte et/ou la rponse (entte et corps) modier la requte et/ou la rponse (entte et corps) appeler les autres ltres

Les ltres sont appells dans lordre de dclaration dans web.xml Le passage dun ltre au suivant se fait par .doFilter(...)

INSA - ASI

TechnoWeb : Servlet

48/74

Filtrage

(3/7)

Parcours de ltres

Les ltres sont appells dans lordre de dclaration dans web.xml Le passage dun ltre au suivant se fait par .doFilter(...)

Filtre 1
doFilter

Filtre 2

Filtre N Servlet

doFilter

...
doFilter

INSA - ASI

TechnoWeb : Servlet

49/74

Filtrage

(4/7)

Exemple de ltre

Filtre.java
import import import import import java.io.*; java.text.*; java.util.*; javax.servlet.*; javax.servlet.http.*;

public class Filtre implements Filter { private SimpleDateFormat formatter = new SimpleDateFormat("E d MMM yyyy, H:m:s.S", Locale.FRANCE); private Date date = new Date(); private FilterConfig fconfig; public void init(FilterConfig fconfig) { this .fconfig = fconfig; } public void destroy() { this .formatter = null; this .date = null; this .fconfig = null; }

...

INSA - ASI

TechnoWeb : Servlet

50/74

Filtrage

(5/7)

Exemple de ltre

Filtre.java
...
public void doFilter(ServletRequest requete, ServletResponse reponse, FilterChain chain) throws ServletException, IOException { ServletContext context = this.fconfig.getServletContext(); HttpServletRequest httpRequete = (HttpServletRequest)requete; PrintWriter writer = reponse.getWriter(); this .date.setTime(System.currentTimeMillis()); context.log("Debut: "+formatter.format(this.date)+" > "+httpRequete.getRequestURL()); reponse.setContentType("text/plain; charset=UTF-8"); reponse.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); writer.println("En-tte ajout par le filtre : " + this.fconfig.getInitParameter("EnTete")); chain.doFilter(requete, reponse); writer.println("Pied de page ajout par le filtre : " + this.fconfig.getInitParameter("PiedDePage")); this .date.setTime(System.currentTimeMillis()); context.log("Fin: "+formatter.format(this.date)+" > "+httpRequete.getRequestURL()); } }

INSA - ASI

TechnoWeb : Servlet

51/74

Filtrage

(6/7)

Exemple : dploiement

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> <filter> <filter-name>ServletFilter</filter-name> <filter-class>Filtre</filter-class> <init-param> <param-name>EnTete</param-name> <param-value>En-tte</param-value> </init-param> <init-param> <param-name>PiedDePage</param-name> <param-value>Pied de page</param-value> </init-param> </filter> <filter-mapping> <filter-name>ServletFilter</filter-name> <url-pattern>/Servlet/*</url-pattern> </filter-mapping>

...

INSA - ASI

TechnoWeb : Servlet

52/74

Filtrage

(7/7)

Exemple : dploiement

web.xml
...
<servlet> <servlet-name>Hello</servlet-name> <servlet-class>Hello</servlet-class> </servlet> <servlet> <servlet-name>Compteur</servlet-name> <servlet-class>Compteur</servlet-class> </servlet> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/Servlet/Hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Compteur</servlet-name> <url-pattern>/Servlet/Compteur</url-pattern> </servlet-mapping> </web-app>

INSA - ASI

TechnoWeb : Servlet

53/74

Partage du contrle
Principe dinvocation

(1/8)

Appel dune ressource partir dune autre Servlet


Deux types dinvocations possibles :
linclusion la dlgation

Linterface ServletRequest met disposition un distributeur de requtes par URL absolue ou relative : RequestDispatcher getRequestDispatcher(String path) Linterface ServletContext met disposition un distributeur de requtes par nom au lieu dune URL : RequestDispatcher getNamedDispatcher(String name)

INSA - ASI

TechnoWeb : Servlet

54/74

Partage du contrle
RequestDispatcher

(2/8)

Deux mthodes importantes


Il y a transmission des objets requte (ServletRequest) et rponse (ServletResponse) void forward(ServletRequest req, ServletResponse rep) : dlgue totalement la ressource appelle, la rponse sera celle de la ressource void include(ServletRequest req, ServletResponse rep) : invoque et inclut la rponse de la ressource la rponse de la servlet Il est possible dajouter de nouveaux attributs la requte

INSA - ASI

TechnoWeb : Servlet

55/74

Partage du contrle
Dlgation

(3/8)

Ache.java
import import import import java.io.*; java.util.*; javax.servlet.*; javax.servlet.http.*;

public class Affiche extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { reponse.setContentType("text/html; charset=UTF-8"); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title> Exemple de dlgation </title>"); out.println("</head>"); out.println("<body>"); out.println("<p> <b>Nombre despaces : </b>"+requete.getAttribute("resultat")+"</p>"); out.println("<p><b> Phrase : </b>\""+requete.getParameter("phrase")+"\"</p>"); out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

56/74

Partage du contrle
Dlgation

(4/8)

AnalyseTexte.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class AnalyseTexte extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { String phrase = requete.getParameter("phrase"); String url; if (phrase != null && !phrase.trim().equals("")) url = "/Servlet/Affiche"; else url = "/delegation.html"; requete.setAttribute("resultat", ""+calculNbMotif(" ", phrase)); RequestDispatcher rd = requete.getRequestDispatcher(url); rd.forward(requete,reponse); }

INSA - ASI

TechnoWeb : Servlet

57/74

Partage du contrle
Dlgation

(5/8)

AnalyseTexte.java
int calculNbMotif(String motif, String phrase) { int nbMotifs = 0; int indice = 0; while ((indice = phrase.indexOf(motif, indice)) != -1) { nbMotifs++; indice++; } return nbMotifs; } }

Utilit
Couramment utilise pour dlguer lachage, le traitement tant fait dans la premire servlet. Le rsultat est transmis une autre servlet via des attributs puis est ach.

INSA - ASI

TechnoWeb : Servlet

58/74

Partage du contrle
Inclusion

(6/8)

Ache.java
import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.Locale;

public class Affiche extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { requete.setCharacterEncoding("ISO-8859-1"); String phrase = requete.getParameter("phrase"); String caracteres = requete.getParameter("caracteres"); if (phrase == null || phrase.trim().equals("")) { RequestDispatcher rd = requete.getRequestDispatcher("/inclusion.html"); rd.forward(requete,reponse); return; } reponse.setContentType("text/html; charset=ISO-8859-1"); reponse.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); PrintWriter out= reponse.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title> Exemple dinclusion </title>"); out.println("</head>"); out.println("<body>");

...

INSA - ASI

TechnoWeb : Servlet

59/74

Partage du contrle
Inclusion

(7/8)

Ache.java
...
out.println("<p><b> Phrase : </b>\""+requete.getParameter("phrase")+"\"</p>"); for(int i=0; i<caracteres.length(); i++) { requete.setAttribute("motif", ""+caracteres.charAt(i)); RequestDispatcher rd = requete.getRequestDispatcher("/Servlet/Analyse"); out.println("<p> <b> Nombre de \""+caracteres.charAt(i)+"\" :</b>"); rd.include(requete,reponse); out.println("</p>"); } out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

60/74

Partage du contrle
Inclusion

(8/8)

AnalyseTexte.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class AnalyseTexte extends HttpServlet { public void doGet(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { String phrase = requete.getParameter("phrase"); String motif = (String)requete.getAttribute("motif"); PrintWriter out = reponse.getWriter(); out.println(calculNbMotif(motif,phrase)); } int calculNbMotif(String motif, String phrase) { int nbMotifs = 0; int indice = 0; while ((indice = phrase.indexOf(motif, indice)) != -1) { nbMotifs++; indice++; } return nbMotifs; } }

INSA - ASI

TechnoWeb : Servlet

61/74

Sessions

(1/4)

API de suivi de session

Chaque session dun client est gre via un objet HttpSession


Rcupration dune session par HttpServletRequest :
HttpSession getSession()

Quelques mthodes de HttpSession :


void setAttribute(String name, Object value) Object getAttribute(String name) void removeAttribute(String name) void setMaxInactiveInterval(int secs) void invalidate()

NB : Les informations relatives au client sont stockes ct serveur

INSA - ASI

TechnoWeb : Servlet

62/74

Sessions
Timeout

(2/4)

Exemple : Compteur & Session

<web-app> ... <session-config> <session-timeout>10</session-timeout> <!-- temps en minutes --> </session-config> ... </web-app>

CompteurSession.java
import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.Locale;

public class CompteurSession extends HttpServlet { private static int compteur = 0; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String message="Vous tes dj venu"; HttpSession session = req.getSession();

...

INSA - ASI

TechnoWeb : Servlet

63/74

Sessions

(3/4)

Exemple : Compteur & Session

CompteurSession.java
...
if (session.getAttribute("DejaVenu") == null) { session.setAttribute("DejaVenu","dejavenu"); message="Bienvenu"; compteur++; } res.setContentType("text/html; charset=UTF-8"); res.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); PrintWriter out = res.getWriter(); out.println("<head>"); out.println("<title> Compteur Session </title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>"+compteur+"</h1>"); out.println("<h1>"+message+"</h1>"); out.println("<a href=CompteurKiller>The Session killer</a>"); out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

64/74

Sessions

(4/4)

Compteur & Session

CompteurSessionKiller.java
import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.util.Locale;

public class CompteurSessionKiller extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String message="Vous navez pas de session en cours"; HttpSession session = req.getSession(); if (session.getAttribute("DejaVenu") != null) { message="Cest la morte session :)"; session.invalidate(); } res.setContentType("text/html charset=UTF-8"); res.setLocale(new Locale(Locale.FRENCH.getLanguage(), Locale.FRANCE.getCountry())); PrintWriter out = res.getWriter(); out.println("<head>"); out.println("<title> Compteur Session </title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>"+message+"</h1>"); out.println("<a href=Compteur>Le retour du compteur !!!</a>"); out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

65/74

Authentication

(1/10)

Mthodes dauthentication

2 mthodes didentication
Utilisation des mcanismes dauthentication du serveur La gestion des comptes et mots de passe dpend du serveur
pour Tomcat gestion des comptes dans conf/tomcat-users.xml pour JBOSS :
1 2

3 4

dclaration dun domaine de scurit dans conf/login-config.xml dclaration des users/roles dans des chiers (ex : conf/props/users.properties et conf/props/roles.properties) dans jboss-web.xml, pointer vers le domaine de scurit dans web.xml, dnir la restriction au rle pour le domaine de scurit

Authentication personnalise gre par des servlets La gestion des comptes et mots de passe est laisse au dveloppeur Problme principal : mots de passe en clair Solution : crypter le canal de communication (HTTPS)

INSA - ASI

TechnoWeb : Servlet

66/74

Authentication

(2/10)

Authentication par le serveur : Servlet secrte

InformationSecrete.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class InformationSecrete extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html; charset=UTF-8"); PrintWriter out = res.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title> Information Secrte </title>"); out.println("</head>"); out.println("<body>"); out.println("<h1> Contreptrie belge : </h1>"); out.println("<p> \"Il fait beau et chaud.\" </p>"); out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

67/74

Authentication

(3/10)

Authentication par le serveur : web.xml

WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!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>InformationSecrete</servlet-name> <servlet-class>InformationSecrete</servlet-class> </servlet> <servlet-mapping> <servlet-name>InformationSecrete</servlet-name> <url-pattern>/Servlet/InformationSecrete</url-pattern> </servlet-mapping>

...

INSA - ASI

TechnoWeb : Servlet

68/74

Authentication

(4/10)

Authentication par le serveur : web.xml

WEB-INF/web.xml
...
<security-constraint> <web-resource-collection> <web-resource-name>contrepetrie</web-resource-name> <description>Une contrepetrie (belge) securisee</description> <url-pattern>/Servlet/InformationSecrete</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>prof</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>contrepetrie</realm-name> </login-config> <security-role> <role-name>prof</role-name> </security-role> </web-app>

INSA - ASI

TechnoWeb : Servlet

69/74

Authentication

(5/10)

Authentication par le serveur : jboss-web.xml et jboss-web.xml

WEB-INF/jboss-web.xml
<?xml version=1.0 encoding=UTF-8 ?> <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN" "http://www.jboss.org/j2ee/dtd/ jboss-web_3_2.dtd"> <jboss-web> <security-domain>java:/jaas/contrepetrie</security-domain> </jboss-web>

JBOSS/server/default/conf/login-cong.xml
<application-policy name="contrepetrie"> <authentication> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required"> <module-option name="usersProperties">props/contrepetrie-users.properties</module-option> <module-option name="rolesProperties">props/contrepetrie-roles.properties</module-option> <module-option name="unauthenticatedIdentity">anonyme</module-option> </login-module> </authentication> </application-policy>

INSA - ASI

TechnoWeb : Servlet

70/74

Authentication

(6/10)

Authentication par le serveur : users/role

JBOSS/server/default/conf/props/contrepetrie-users.properties
alex=alex anonyme=anonyme tt=tt

JBOSS/server/default/conf/props/contrepetrie-roles.properties
alex=prof anonyme=eleve tt=eleve

INSA - ASI

TechnoWeb : Servlet

71/74

Authentication

(7/10)

Authentication par formulaire

InformationSecrete.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class InformationSecrete extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html; charset=UTF-8"); PrintWriter out = res.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Information secrte</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Contreptrie</h1>"); out.println("<p>\"Je glisse dans la piscine\"</p>"); out.println("</body>"); } }

INSA - ASI

TechnoWeb : Servlet

72/74

Authentication
web.xml

(8/10)

Authentication par formulaire

<?xml version="1.0" encoding="ISO-8859-1"?> <!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>InformationSecrete</servlet-name> <servlet-class>InformationSecrete</servlet-class> </servlet> <servlet-mapping> <servlet-name>InformationSecrete</servlet-name> <url-pattern>/Servlet/InformationSecrete</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>Contrepetrie</web-resource-name> <url-pattern>/Servlet/InformationSecrete</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>prof</role-name> </auth-constraint> </security-constraint>

INSA - ASI

TechnoWeb : Servlet

73/74

Authentication
web.xml

(9/10)

Authentication par formulaire

<login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/erreur.html</form-error-page> </form-login-config> </login-config> <security-role> <role-name>prof</role-name> </security-role> </web-app>

erreur.html
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html> <head><title>Authentification par formulaire</title></head> <body> <hr><h1>Erreur dauthentification</h1><hr> </body> </html>

INSA - ASI

TechnoWeb : Servlet

74/74

Authentication

(10/10)

Authentication par formulaire

login.html
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html> <head> < title >Authentification par formulaire</title> </head> <body> <hr><form action="j_security_check" method="post"> Login : <input type="text" name="j_username"><br/> Pass : <input type="password" name="j_password"><br/> <input type="submit"> </form><hr/> </body> </html>

Vous aimerez peut-être aussi