Académique Documents
Professionnel Documents
Culture Documents
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
API
7
Encodage
8
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)
INSA - ASI
TechnoWeb : Servlet
5/74
Introduction
(3/9)
INSA - ASI
TechnoWeb : Servlet
6/74
Introduction
Application Web
(4/9)
INSA - ASI
TechnoWeb : Servlet
7/74
Introduction
Application J2EE
(5/9)
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)
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)
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)
<?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>
INSA - ASI
TechnoWeb : Servlet
12/74
API
(1/6)
Application Web
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
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>
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)
INSA - ASI
TechnoWeb : Servlet
16/74
API
(5/6)
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)
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) }
INSA - ASI
TechnoWeb : Servlet
18/74
Encodage
(1/4)
... 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)
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)
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)
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)
pour un champ de formulaire ayant plusieurs valeurs (liste choix multiples, cases cocher, etc.),
INSA - ASI
TechnoWeb : Servlet
23/74
Paramtres
(2/15)
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)
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)
INSA - ASI
TechnoWeb : Servlet
30/74
Paramtres
(9/15)
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)
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
Partager des informations entre plusieurs Servlet :
le partage est eectu travers le contexte dexcution gr par ServletContext
INSA - ASI
TechnoWeb : Servlet
33/74
Paramtres
web.xml
(12/15)
<?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)
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)
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)
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)
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)
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)
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)
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)
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)
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
INSA - ASI
TechnoWeb : Servlet
47/74
Filtrage
(2/7)
Mise en uvre
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)
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)
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)
INSA - ASI
TechnoWeb : Servlet
62/74
Sessions
Timeout
(2/4)
<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)
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)
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)
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)
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)
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)
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)
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)
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)
<?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)
<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)
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>