Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

PL2 15servlets

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 64

Applications Web Java

Servlets
Philippe Genoud

dernière modification : 04-02-2020

©
© Philippe
Philippe GENOUD
GENOUD UGA
UJF Février 2020
2005 1
La plateforme Java EE
 les Servlets s'inscrivent dans la plateforme Java EE (Java Entreprise Edition)
 Java EE (Java Enterprise Edition), anciennement J2EE (Java 2 Entreprise Edition) et maintenant Jakarta EE est
un ensemble de spécifications étendant JSE pour le développement d’applications d’entreprise.

 La spécification Java EE définit


 Un ensemble d’API pour les applications d’entreprises (applications réparties, services web, mapping
Objet/Relationnel pour la persistance des données…),
 Un plate-forme (Java EE Platform) à base de composants pour héberger et exécuter les applications
(serveurs Java EE)
 Une suite de tests (Java EE Compatibility Test Suite) pour vérifier la compatibilité des implémentations

 Une implémentation de référence (Java EE Reference Implementation): GlassFish ;

 S'appuie sur un modèle d'architecture multi-tiers (multi-couches)

© Philippe GENOUD UGA Février 2020 2


Java EE - APIs
 Java EE inclus de nombreuses API couvrant de nombreuses fonctionnalités
 pages web dynamiques, lecture écriture transactionnelle dans des BD, files d’attentes distribuées…
 Web
 Servlet: gestion de requêtes HTTP. API de bas niveau, les autres spécifications Java EE s’appuient sur elle,

 JSP (Java Server Pages) : pages web dynamiques,

 JSF (Java Server Faces): construction d’interfaces utilisateur à partir de composants;

 EL (Unified Expression Language): langage simple pour lier des composants (JSP ou JSF) avec des objets Java,

 WebSocket: gestion de connexions WebSocket.

 Services Web
 Java API for XML Web Services: pour la création de services web SOAP,

 Java API for RESTful Web Services: support pour créer des services web conformes aux principes architecturaux REST
(Representational State Transfer);
 Java API for JSON Processing: gestion d’informations encodées au format JSON format;,

 Java API for JSON Binding: conversion d’informations JSON en classes et objets Java et inversement,

 Java Architecture for XML Binding: transormation de XML en objets Java,

© Philippe GENOUD UGA Février 2020 3


Java EE - APIs
 Spécifications d’entreprise
 EJB (Enterprise JavaBean) ensemble d’APIs légères (lightweigh) pour la définition d’objets métiers (Entreprise Beans)
pris en charge par un container d’objets (EJB container)
 transactions (en utilisant JTA), appels de procédures à distance (RMI ou RMI-IIOP), gestion de la concurrence,
injection de dépendances, control d’accès.
 JPA (Java Persistence API) : ORM (Object-Relational Mapping) entre tables d’un SGBDR et des classes Java.

 JTA (Java Transaction API) : interaction avec le support transactionnel offert par JEE with the transaction support
offert par Java EE.
 JMS (Java Message Service) : création, envoi, réception de messages d’un système de messagerie d’entreprise.

 Autres spécifications
 Validation (Bean Validation API) : fournit un moyen unifié pour définir des contraintes sur les objets métiers (beans,
par exemple les classes de modèle JPA model) qui peuvent être appliquées sur plusieurs couches (persistance JPA,
vues JSF).
 Batch Applications: exécution de programmes en tâches de fond.

© Philippe GENOUD UGA Février 2020 4


Architecture des applications Java EE
 Architecture multi-tiers

Client léger Tier client Poste client


(navigateur web)

Conteneur WEB
Client riche
présentation (application Java)
Pages JSP
Pages JSP Servlets
Tier web

Serveur JEE
Serveur Conteneur EJB Tier métier
métier d'applications EJB EJB EJBEJB
EJB
JEE

Serveur
Tier Système
données de bases
d'Information de
l'Entreprise de données

• Logique de l'application :
– Composants web (Servlet, JSP,JFS)
– Composants métiers (EJB Entreprise Java Beans)
• Services standards (cycle de vie des composants, multithreading, transactions, persistance…) pris en charge par les conteneurs
Web et EJB du serveur d'application JEE

© Philippe GENOUD UGA Février 2020 5


Situation actuelle de Java EE

 Différentes implémentations certifiées:


 Processus de certification - TCK (Test Compatibility Kit) (~ 20000 tests)
 Serveurs JEE8
 GlassFish server Open Source Edition : implementation de référence,

 WildFly (RedHat),

 WebSphere Application Server Liberty (IBM)

 Open Liberty (IBM)

 Serveurs JEE7

 JBoss Enterprise Application Platform (RedHat)

 Oracle WebLogic Server

 … http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.html

© Philippe GENOUD UGA Février 2020 6


Servlet ?

 Servlet (https://javaee.github.io/tutorial/servlets001.html#BNAFE)
 classe Java pour étendre les possibilités de serveurs hébergeant des applications accédées par un
modèle de programmation de type requête-réponse

JVM

(1) requête (2) requête

(4) réponse (3) réponse


objet Servlet
Poste client Serveur

 servlets peuvent potentiellement répondre à tout type de requête mais dans la réalité sont le plus souvent
utilisées pour étendre des applications hébergées par un serveur web  requêtes HTTP

© Philippe GENOUD UGA Février 2020 7


Servlet ?
 technologie java propose des classes de servlets spécifiques pour le protocole HTTP

contenu statique

réponse HTTP

HTTP frontend
requête HTTP
(1) requête HTTP

Client (4) réponse HTTP contenu dynamique


Poste client (browser)

Serveur Web

API JDBC
Serveur BD
objets ServletHTTP

 les servlets génèrent


 des pages web dynamiques (comme PHP, ASP, ASP.NET, ...)
 de manière plus générale n'importe quel contenu web dynamique (HTML, XML, JSON, etc …)

 les servlets s'exécutent dans des serveurs dédiés (servlets containers)

© Philippe GENOUD UGA Février 2020 8


Conteneurs de servlets
 Conteneur de servlets
 gère les échanges avec le client (protocole HTTP)
 aiguille les requêtes vers les servlets
 charge/décharge les servlets
 Les servlets sont instanciées une seule fois, ensuite le traitement des requêtes s'effectue de manière concurrente
dans des fils d'exécution (threads) différents
conteneur de servlets
différentes servlets

HTTP frontend
req1 client 1 pour différentes
req2 client 1 requêtes
req2 client 2
req3 client3

servlet3 servlet2 servlet1


Serveur Web

une servlet n'est


instanciée qu'une fois et
Les servlets sont peut servir simultanément
 différents types de conteneur de servlets chargées/instanciées plusieurs clients
dynamiquement
 conteneurs légers : Apache Tomcat, Jetty, Resin
 conteneurs Java EE complets : Glassfish, WildFly, anciennement JBoss (RedHat), WebSphere (IBM)….
 Java assure la portabilité d'un conteneur à un autre
© Philippe GENOUD UGA Février 2020 9
les versions de l'API Servlet
Version Date de sortie Plateforme
Servlet 4.0 Août 2017 JavaEE 8 (fin 2017)
Servlet 3.1 Mai 2013 JavaEE 7
Servlet 3.0 Décembre 2009 JavaEE 6, JavaSE 6
Servlet 2.5 Septembre 2005 JavaEE 5, JavaSE 5
Servlet 2.4 Novembre 2003 J2EE 1.4, J2SE 1.3
Servlet 2.3 Aout 2001 J2EE 1.3, J2SE 1.2
Servlet 2.2 Aout 1999 J2EE 1.2, J2SE 1.2
Servlet 2.1 Novembre 1998 --
Servlet 2.0 -- --
Servlet 1.0 Juin 1997 --
documentation API Java EE7 : http://docs.oracle.com/javaee/7/api/

documentation API Java EE8 : https://javaee.github.io/javaee-spec/javadocs/

© Philippe GENOUD UGA Février 2020 10


L'API servlets de Java EE
 Deux packages :
 javax.servlet : support de servlets génériques indépendants du protocole
 javax.servlet.http : ajoute fonctionnalités spécifiques à HTPP
javax.Servlet

<<interface>> Servlet <<interface>> ServletContext


+init():void +getContextPath():String
+destroy():void +getAttribute(name:String):Object
+service(req:ServletRequest, resp: ServletResponse) +setAttribute(name:String, o:Object):void
... ...

GenericServlet
+service(req:ServletRequest, resp: ServletResponse) <<interface>> ServletRequest <<interface>> ServletResponse
+init():void
+destroy():void +getAttribute(name:String):Object +setContentType(type:String):void
+getServletInfo():String +setAttribute(name:String, o:Object):void +getWriter():PrintWriter;
+getServletConfig():ServletConfig ... ...
+getServletContext():ServletContex
...

javax.Servlet.http

HttpServlet <<interface>> HttpServletRequest <<interface>> HttpServletResponse


+service(req:ServletRequest, resp: ServletResponse) +getHeader(name:String):String +addCookie(c: Cookie):void
#service(req:HttpServletRequest, resp: HttpServletResponse) +getSession():HttpSession +addHeader(name, value : String):void
+doGet(req:HttpServletRequest , resp:HttpServletResponse) ... ...
+doPost(req:HttpServletRequest , resp:HttpServletResponse)
+doPut(req:HttpServletRequest , resp:HttpServletResponse)
+doDelete(req:HttpServletRequest , resp:HttpServletResponse) <<interface>> HttpSession
+getAttribute(name:String):Object
+setAttribute(name:String, o:Object):void
...
http://docs.oracle.com/javaee/7/api/
© Philippe GENOUD UGA Février 2020 11
L'API servlets de JEE
javax.Servlet  définir une servlet consiste à :
<<interface>> Servlet  sous classer HttpServlet
+init():void
+destroy():void  redéfinir une ou plusieurs des méthodes doXXX
+service(req:ServletRequest, resp: ServletResponse)
...
package mypackage;
import java.io.IOException;
import ...
GenericServlet
...
+service(req:ServletRequest, resp: ServletResponse)
+init():void
+destroy():void public class MyServlet extends HttpServlet {
+getServletInfo():String /**
+getServletConfig():ServletConfig * Handles the HTTP <code>GET</code> method.
+getServletContext():ServletContex
... * @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
javax.Servlet.http
*/
@Override
HttpServlet protected void doGet(HttpServletRequest request,
+service(req:ServletRequest, resp: ServletResponse)
HttpServletResponse response)
#service(req:HttpServletRequest, resp: HttpServletResponse) throws ServletException, IOException {
+doGet(req:HttpServletRequest , resp:HttpServletResponse) ...
+doPost(req:HttpServletRequest , resp:HttpServletResponse)
+doPut(req:HttpServletRequest , resp:HttpServletResponse) }
+doDelete(req:HttpServletRequest , resp:HttpServletResponse)
@Override
protected void doPost(HttpServletRequest request,
mypackage
HttpServletResponse response)
throws ServletException, IOException {
MyServlet ...
}
+doGet(req:HttpServletRequest , resp:HttpServletResponse)
+doPost(req:HttpServletRequest , resp:HttpServletResponse) }

© Philippe GENOUD UGA Février 2020 12


Cycle de vie d'une servlet
serveur Web sous classe de HtppServlet

requête GET
réponse doGet(…)

service()
requête POST
doPost(…)
réponse

méthodes implémentées par la sous classe

 Cycle de vie géré par le serveur (container)


 Initialisation :
 Chargement de la classe (au démarrage ou sur requête).

 Instanciation d’un objet.

 Appel de la méthode init() (par exemple : ouverture de lien JDBC)

 Utilisation :
 Appel de la méthode service()

 Dans le cas d’une HttpServlet : appel vers doGet(), doPost().

 Destruction :
 Peut être provoquée pour optimiser la mémoire

 appel de la méthode destroy()

© Philippe GENOUD UGA Février 2020 13


Première package fr.im2ag.m2cci.servletsdemo.servlets;

Servlet
import java.io.IOException;
import java.io.PrintWriter;
import java.utilDate;
import javax.servlet.ServletException; imports des différentes classes et interfaces
import javax.servlet.annotation.WebServlet; nécessaires à l'écriture du code de la servlet.
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
annotation définissant l'url
associée à cette servlet @WebServlet(name = "HelloWorldServlet", urlPatterns = {"/HelloWorld"})
(servlet Mapping)
avant JEE6 public class HelloWorldServlet extends HttpServlet { la servlet hérite de la classe HttpServlet
ces infos /**
étaient dans * Handles the HTTP <code>GET</code> method.
un fichier de * @param request servlet request
configuration: * @param response servlet response
web.xml * @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
redéfinition de la méthode doGet protected void doGet(HttpServletRequest request, HttpServletResponse response)
traitant les requêtes HTTP GET. throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet HelloWorldServlet</title>");
out.println("</head>"); construction de la réponse à la requête en
out.println("<body>"); utilisant l'objet PrintWriter fournit par
out.println("<h1>Hello World!!</h1>"); le paramètre HttpServletResponse.
out.println("<h2>Reponse envoyée le " + new Date() + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
} © Philippe GENOUD UGA Février 2020 14
Invoquer la servlet
http://localhost:8084/ServletsDemos/HelloWorld

protocole serveur contexte de la servlet url pattern pour la servlet


(nom de l'application web (défini par le servlet
sur le serveur*) mapping **)

* un serveur peut héberger plusieurs applications


** une application peut être composée de plusieurs servlets

HelloWorldServlet
serveur Web sous classe de HtppServlet

requête GET
doGet(…)
service()
réponse

© Philippe GENOUD UGA Février 2020 15


objets HttpServletRequest et HttpServletResponse

 passés en paramètre des méthodes service() , doGet() , doPost() , doXXX()…


 instanciés par le conteneur de servlets, qui les transmet à la méthode service.

conteneur de servlets
requête HTPP

1 Création d'un objet HttpServletRequest


contient les informations relatives à la requête

réponse
2 Création d'un objet HttpServletResponse
permettra de construire et renvoyer une réponse au client

Envoi d'un message service(req,rep)


3 à la servlet concernée

Analyse de la requête service(req,rep) service(req,rep)


décrite par l'objet
HttpServletequest
4 doXXX(req,rep) doXXX(req,rep)
Utilisation de l'objet
HttpServletResponse
servlet1 servlet2
pour l’envoi de la réponse sous classe de HtppServlet sous classe de HtppServlet
au client
© Philippe GENOUD UGA Février 2020 16
Objets HttpServletRequest et HttpServletResponse
 HttpServletRequest :
 Contexte de l’appel javax.Servlet

 Paramètres de formulaires <<interface>> ServletRequest


<<interface>> ServletResponse
+getAttribute(name:String):String
 Cookies +getAttribute(name:String):Object
+setContentType(type:String):void
+getWriter():PrintWriter;
+setAttribute(name:String, o:Object):void
...
 Headers ...

 ...
javax.Servlet.http

 HttpServletResponse
<<interface>> HttpServletRequest <<interface>> HttpServletResponse
 Contrôle de la réponse +getHeader(name:String):String
+getSession():HttpSession
+addCookie(c: Cookie):void
+addHeader(name, value : String):void

 Type de données ... ...

 Données
 Cookies
 Status
 ...

© Philippe GENOUD UGA Février 2020 17


Utilisation des objets Request et Response
 Un pattern classique pour l'implémentation d'une méthode service (doXXX) d'une servlet est le suivant:
1. Extraire de l'information de la requête (paramètre request : HttpServletRequest)
2. Accéder éventuellement à des ressources externes
3. Produire une réponse sur la base des informations précédentes
a) Récupérer un flux de sortie pour l'écriture de la réponse (à l’aide du paramètre response : HttpServletResponse)

Object
Pour envoyer des données sous forme de Pour envoyer des données sous forme binaire
chaînes de caractères
Writer OutputStream
PrintWriter out = resp.getWriter(); java.io ServletOutputStream out
= resp.getOutputStream();
PrintWriter ServletOutputStream

b) Définir les entêtes (HTPP headers) de la réponse

resp.setContentType("text/html"); indiquer le type du contenu resp.setContentType("image/png");

Types MIME (Multipurpose Internet Mail Extensions) resp.setContentType("application/pdf");


http://www.iana.org/assignments/media-types/

c) Ecrire le contenu (corps) de la réponse sur le flux de sortie


byte[] tab = ...;
out.println("<p>blabla...</p>");
directement avec l'objet out ...
out.print(...)
out.write(tab);
out.print(...);

en passant par API spécialisées Document document = new Document() ;


ex: iText (http://itextpdf.com/ ) pour pdf PdfWriter.getInstance(document,out) ;
http://www.ibm.com/developerworks/java/library/os-javapdf/index.html?ca=dat

© Philippe GENOUD UGA Février 2020 18


Servlets et formulaires

paramètres de la requête
formulaire HTML
http://localhost:8084/ServletsDemos/HelloWorld2?nom=Joe+Moose&nb=5 conteneur de servlets

requête GET/POST
nom "Joe Moose" Objet HttpServletRequest tableau associatif
nb (Map<String,String>) pour les paramètres
"5"

réponse
Objet HttpServletResponse

service(req,rep)
interrogation de l'objet utilisation de l'objet
HttpServletRequest pour HttpServletResponse
récupérer les paramètres de la pour construire et envoyer
doXXX(req,rep) la réponse au client qui a
requête
émis la requête

String nom = request.getParameter("nom")


response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
...

© Philippe GENOUD UGA Février 2020 19


Servlets et formulaires
<!DOCTYPE html>
<html>
<head>
<title>Formulaire Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<form action="HelloWorld2">
Votre nom :
<input type="text" name="nom" value="" size="20" /><br/>
Nombre de répétitions : @WebServlet(name = "HelloWorld2Servlet", urlPatterns = {"/HelloWorld2"})
<input type="text" name="nb" value="5" size="3" /><br/> public class HelloWorld2Servlet extends HttpServlet {
<input type="submit" value="Soumettre" />
</form> @Override
</body> protected void doGet(HttpServletRequest request, HttpServletResponse response)
</html> throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String leNom = request.getParameter("nom");
int nbRepet = Integer.parseInt(request.getParameter("nb")); getParameter()
out.println("<html>"); retourne des String
out.println("<head>");
out.println("<title>Servlet HelloWorldServlet</title>");
out.println("</head>");
out.println("<body>");
for (int i = 0; i < nbRepet; i++) {
out.println("<h1>Hello " + leNom + "</h1>");
Génération de la }
réponse HTML out.println("<h2>Réponse envoyée le " + new Date() + "</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}

© Philippe GENOUD UGA Février 2020 20


Execution concurrente des Servlets
 Serveur web multi-threadé Conteneur de
servlets Thread
 Par défaut une servlet n'est
instanciée qu'une seule fois Thread Thread
Créer un pool de
 La même instance peut servir threads
plusieurs requêtes
Instancier la servlet
simultanément Servlet
 le conteneur crée un
thread (processus léger) Appeler init()
par requête pour pouvoir initialisation
les traiter en parallèle
Requête Affecter une requête à un thread Appeler service()
HTTP 1
 Attention !! Les attributs de la Requête Appeler service() Exécuter le
Affecter une requête à un thread
servlet deviennent des HTTP 2 service
ressources partagées
Réponse
 ils sont accédés de manière Exécuter le
HTTP 1
concurrente par chaque fil service
d'exécution Réponse
HTTP 2 Terminer le pool de threads

Appeler destroy()

© Philippe GENOUD UGA Février 2020 21


Execution des servlets
@WebServlet(name = "Factorielle", urlPatterns = {"/Factorielle"})
public class Factorielle extends HttpServlet {

protected int nombre; Requête 1: factorielle?nombre=3


protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = Integer.parseInt(request.getParameter("nombre"));
out.print("<h2>" + nombre + "! = ");
int fact = 1;
for (int i = 2; i <= nombre; i++) {
fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}

© Philippe GENOUD UGA Février 2020 22


tion des servlets
@WebServlet(name = "Factorielle", urlPatterns = {"/factorielle"})
public class Factorielle extends HttpServlet {

protected int nombre; Requête 1: factorielle?nombre=3


protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = Integer.parseInt(request.getParameter("nombre"));
out.print("<h2>" + nombre + "! = ");
int fact = 1;
for (int i = 2; i <= nombre; i++) {
fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}

© Philippe GENOUD UGA Février 2020 23


Execution des servlets
@WebServlet(name = "Factorielle", urlPatterns = {"/Factorielle"})
public class Factorielle extends HttpServlet {

protected int nombre; Requête 1: factorielle?nombre=3


protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = Integer.parseInt(request.getParameter("nombre"));
out.print("<h2>" + nombre + "! = ");
int fact = 1;
for (int i = 2; i <= nombre; i++) {
fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
} • La servlet n'est instanciée qu'une seule fois,
} • Le conteneur utilise des threads différents
pour répondre à chaque requête
• nombre est accédée de manière concurrente

© Philippe GENOUD UGA Février 2020 24


Execution des servlets
servlet
nombre
30
thread1 thread2

protected void doGet(...) {


response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Requête 1: factorielle?nombre=3 try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = 3 1 1 nombre = Integer.parseInt(request.getParameter("nombre"));
out.print("<h2>" + nombre + "! = ");
int fact = 1;
for (int i = 2; i <= nombre; i++) {
fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}

© Philippe GENOUD UGA Février 2020 25


Execution des servlets
servlet
nombre
30
thread1 thread2

protected void doGet(...) {


response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Requête 1: factorielle?nombre=3 try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = 3 1 1 nombre = Integer.parseInt(request.getParameter("nombre"));
out.print("<h2>" + nombre + "! = ");
int fact = 1;
début de l'itération avec for (int i = 2; i <= nombre; i++) {
nombre = 3 fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}

© Philippe GENOUD UGA Février 2020 26


Execution des servlets
servlet
nombre
35
0
thread1 thread2

protected void doGet(...) {


response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Requête 1: factorielle?nombre=3 try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = 3 1 1 nombre = Integer.parseInt(request.getParameter("nombre")); 2
out.print("<h2>" + nombre + "! = ");
int fact = 1;
début de l'itération avec for (int i = 2; i <= nombre; i++) {
nombre = 3 fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
nombre = 5 2 }

© Philippe GENOUD UGA Février 2020 27


Execution des servlets
servlet
nombre
5
0
3
thread1 thread2

protected void doGet(...) {


response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Requête 1: factorielle?nombre=3 try {
out.println("<html>");
out.println("<head>");
out.println("<title>Factorielle</title>");
out.println("</head>");
out.println("<body>");
nombre = 3 1 1 nombre = Integer.parseInt(request.getParameter("nombre")); 2
out.print("<h2>" + nombre + "! = ");
int fact = 1;
début de l'itération avec for (int i = 2; i <= nombre; i++) {
nombre = 3 fact *= i;
}
out.println(fact + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
nombre = 5 2 }
fin de l'itération avec
nombre = 5

3! = 120

5! = 120

© Philippe GENOUD UGA Février 2020 28


Exécution des servlets
 Solutions
 Sections critiques :
 Utilisation du mot clé synchronized (blocs synchronisés ne pouvant être exécutés que par un seul
thread à la fois)
 http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html.

 Modèle d’exécution : 1 instance par thread


 Implémenter l’interface SingleThreadModel

 déprécié depuis la version 2.4 des servlets

© Philippe GENOUD UGA Février 2020 29


Utilisation d'autres ressources
 Le traitement d'une requête HTTP par une servlet peut nécessiter l'utilisation d'autres ressources
 inclusion d'une page HTML statique
 redirection vers une autre servlet ou page JSP
 Réalisé à l'aide d'un objet javax.servlet.RequestDispacher

<<interface>> RequestDispatcher
+ forward(servletRequest req, ServletResponse rep) : void
+ include(servletRequest req, ServletResponse rep) : void

 Obtention d'un objet ResquestDispacher


 via un objet javax.servlet.ServletContext
 via un objet javax.servlet.http.HttpServletRequest
 RequestDispatcher getRequestDispatcher(java.lang.String path)
 path : chaîne de caractères précisant le chemin de la ressource vers laquelle la requête doit être transférée

 doit commencer par un '/' et est interprété comme relatif au contexte de l'application

© Philippe GENOUD UGA Février 2020 30


RequestDispatcher : include
 Exemple: insérer dans la réponse des fragments de code HTML
package fr.im2ag.m2cci.servletsdemo.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import …..

@WebServlet(name = "HelloInclude", urlPatterns = {"/demoInclude"})


public class HelloInclude extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
// inclusion de l'en tête
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/includes/header.html");
dispatcher.include(request, response);
// contenu généré par la servlet
for (int i = 0; i < 5 ; i++) {
out.println("<h3>Hello Include</h3>");
}
// inclusion du pied de page
getServletContext().getRequestDispatcher("/includes/footer.html").include(request, response);
} finally {
out.close();
}
}
}

© Philippe GENOUD UGA Février 2020 31


RequestDispatcher : include
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/includes/header.html");
dispatcher.include(request, response);
...
getServletContext().getRequestDispatcher("/includes/footer.html").include(request, response);

chemins relatifs au contexte de l'application


ExemplesCours
header.html
<!DOCTYPE html>
<html>
<head>
<title>M2CCI-AI</title>
<meta charset="UTF-8" />
<link href="./styles/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header>
<a href="http://ufrima.imag.fr/"><img src="./images/logoUFRIM2AGPetit.png"/></a>
<h1>M2 CCI : Applications Internet</h1>
<a href="http://www.ujf-grenoble.fr"><img src="./images/aiLogo.png"/></a>
</header>

footer.html
<footer>
<p class="auteur"><small>&copy; Philippe Genoud</small></p>
</footer>
</body>
</html>

© Philippe GENOUD UGA Février 2020 32


RequestDispatcher : forward
package fr.im2ag.m2cci.servletsdemo.servlets;
 redirige vers une autre
ressource pour produire import java.io.IOException;
...
la réponse.
@WebServlet(name = "HelloForward", urlPatterns = {"/demoForward"})
public class HelloForward extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int noServlet = Integer.parseInt(request.getParameter("no"));
if (noServlet == 1) {
getServletContext().getRequestDispatcher("/demoForward1").forward(request, response);
} else {
getServletContext().getRequestDispatcher("/index.html").forward(request, response);
}
}
}
servlet
Servlet1

(url pattern
http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO
servlet /demoForward1)
HelloForward
http://localhost:8084/ExemplesCours/demoForward?no=2

index.html

© Philippe GENOUD UGA Février 2020 33


RequestDispatcher : forward
...
@Override
 lesobjets request et response de la protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
servlet initiale sont transmis à la int noServlet = Integer.parseInt(request.getParameter("no"));
if (noServlet == 1) {
ressource vers laquelle la requête est getServletContext().getRequestDispatcher("/demoForward1").forward(request, response);
} else {
redirigée getServletContext().getRequestDispatcher("/index.html").forward(request, response);
}
}
...
...
@WebServlet(name = "Servlet1", urlPatterns = {"/demoForward1"})
public class Servlet1 extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) servlet
throws ServletException, IOException { Servlet1
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try { (url pattern
out.println("<html>"); http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO /demoForward1)
servlet
out.println("<head>"); HelloForward
out.println("<title>Exemple Forward</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello " + request.getParameter("nom") + "</h1>");
out.println("<h3>Réponse produite par Servlet 1</h3>");
out.println("</body>");
out.println("</html>");
} finally {
 paramètres de request sont ceux de la
}
out.close(); requête originale
}
}

© Philippe GENOUD UGA Février 2020 34


RequestDispatcher : forward
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {  la ressource appelante peut transmettre
int noServlet = Integer.parseInt(request.getParameter("no"));
if (noServlet == 1) { des informations supplémentaires via les
request.setAttribute("demandeur","HelloForwardBis"); attributs de la requête
getServletContext().getRequestDispatcher("/demoForward2").forward(request, response);
} else {
getServletContext().getRequestDispatcher("/index.html").forward(request, response);
} ...
} @WebServlet(name = "Servlet2", urlPatterns = {"/demoForward2"})
public class Servlet1 extends HttpServlet {

@Override
http://localhost:8080/ExemplesCours/demoForward?no=1&nom=TOTO servlet protected void doGet(HttpServletRequest request, HttpServletResponse response)
Servlet2 throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
servlet out.println("<html>");
HelloForwardBis out.println("<head>");
(url pattern
/demoForward2) out.println("<title>Exemple Forward</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello " + request.getParameter("nom") + "</h1>");
out.println("<h3>Réponse produite par Servlet 2</h3>");
Les paramètres sont des String String origine = (String) request.getAttribute("demandeur");
Les attributs peuvent être des objets quelconques out.println("<h3>à la demande " + origine + "</h3>");
out.println("</body>");
out.println("</html>");
public void setAttribute(String name, Object value) } finally {
out.close();
}
public Object getAttribute(String name) }
}

© Philippe GENOUD UGA Février 2020 35


RequestDispatcher : forward
 forward comporte plusieurs contraintes :
1  la servlet d'origine ne doit pas avoir déjà expédié des informations vers le client sinon une exception
java.lang.IllegalStateException est lancée
2  si des informations sont déjà présentes dans le buffer de la réponse mais n'ont pas encore été envoyées, elles sont effacées lorsque le
contrôle est transmis à la deuxième ressource
3  lorsque la deuxième ressource a terminé le traitement de la requête, l'objet réponse n'est plus utilisable par la première pour produire
du contenu
int noServlet = Integer.parseInt(request.getParameter("no"));

PrintWriter out = response.getWriter();


try {
if (noServlet == 1) {
response.setContentType("text/html;charset=UTF-8");
out.println("<h3>Cet en tête n'apparaît pas</h3>");
out.println("</body>");
out.println("</html>");
2 si on ne force pas le vidage du buffer par reponse.flushBuffer()
1 out.flushBuffer();
getServletContext().getRequestDispatcher("/demoForward1").forward(request, response);
} else {
getServletContext().getRequestDispatcher("/demoForward3").forward(request, response);
out.println("<h3>Ce texte n'apparait pas</h3>");
out.println("</body>");
3
out.println("</html>");
}
} finally {
out.close();
}

© Philippe GENOUD UGA Février 2020 36


Gestion des Exceptions
 Que se passe t'il lorsque cette servlet traite cette requête ?
http://localhost:8080/TestServletException/testException?nb=1Z&nom=WORLD

traitement de l'exception et
envoi d'une réponse au client
appels 8
Container:
1 Tomcat
7
TestExceptionServlet:
service()
2 6
TestExceptionServlet:
doGet()
3 TestExceptionServlet: 5 remonté de l'exception jusqu'à trouver
processRequest() un bloc catch l'attrapant
4
objet NumberFormatException
lancé par Integer.parseInt()

© Philippe GENOUD UGA Février 2020 37


Gestion des Exceptions
 chercher dansla stack trace les
appels de votre code applicatif

http://localhost:8080/TestServletException/testException?nb=1Z&nom=WORLD traitement de l'exception et


envoi d'une réponse au client
appels 8
Container:
1 Tomcat
7
TestExceptionServlet:
service()
2 6
TestExceptionServlet:
doGet()
3 TestExceptionServlet: 5 remonté de l'exception jusqu'à trouver un
processRequest() bloc catch l'attrapant
4
objet NumberFormatException
lancé par Integer.parseInt()

© Philippe GENOUD UGA Février 2020 38


Gestion des exceptions

 Fichier journal (log)


 Conserver sur un support sûr des événements survenus dans un système ou une application (serveur)
 Un ou plusieurs fichiers journaux (log files) générés en cours d'exécution
 enregistrent des informations sur le déroulement de l'application.
– Nature de l'événement, Date et heure, Gravité
– …
 Utilisés pour :
 Produire des statistiques sur utilisation du système (ex: log du serveur Apache)

 Détecter des problèmes d'exécution

 Reprise après panne

 …

 API de login
 java.util.log, Log4J, SL4J, JULI …

© Philippe GENOUD UGA Février 2020 39


Gestion des exceptions
 Fichier journal du serveur Tomcat Si le l'onglet du fichier log n'apparait pas
dans la fenêtre output
dans l'IDE NetBeans

Onglet log dans la


fenêtre output

clic sur un élément de la stack trace vous


positionne à la ligne correspondante dans
l'éditeur de code

l'onglet affiche l'ensemble du fichier journal qui est stocké sur le disque dur et n'est pas effacé entre les différentes exécutions du serveur
Pour voir la dernière erreur bien se placer au bas du fichier log et vérifier les dates et heures

© Philippe GENOUD UGA Février 2020 40


Gestion des exceptions – fichiers logs
 Où se trouvent les fichiers logs ? cela dépend
 de l'OS et de l'utilisation qui est faite de Tomcat
 sur un serveur de test ou de production

 sur une machine de développement avec ou non intégration à un IDE (Netbeans, Eclispe….)

 Tomcat intégré dans


NetBeans

utilisation d'une configuration privée. utilisation directe du répertoire


Indispensable sur machine partagée d'installation du serveur

/var/lib/tomcat{X}/logs
Windows
Sous Windows dans
repertoire NetBeans
situé dans le profil
utilisateur

sous linux dans


~/.netbeans
Linux/Debian
• /etc/tomcat{X} configuration
• /usr/share/tomcat{X} runtime
• /var/lib/tomcat{X}

© Philippe GENOUD UGA Février 2020 41


Gestion des exceptions
 Traces: Ecrire dans le journal
 méthodes log(String mess) et log(String mess, Throwable t) héritées de HttpServlet

© Philippe GENOUD UGA Février 2020 42


Gestion des exceptions
 Traces
 System.out.println écrit dans le fichier output du serveur

© Philippe GENOUD UGA Février 2020 43


Gestion des exceptions
 NumberFormatException une RunTimeException, mais qu'en est-il des exceptions contrôlées (par ex.
SQLException)

Faire remonter l'exception Attraper l'exception et la traiter

Ce n'est que reporter le problème, la méthode doGet


devra nécessairement l'attraper
redéfinition:
signature ne
peut être
changée

© Philippe GENOUD UGA Février 2020 44


Gestion des exceptions
 traiter une exception contrôlée

Trace partielle. Trace complète avec la cause mère. Permet de


Ne donne que la position de la ServletException. tracer l'exception au plus prêt.

© Philippe GENOUD UGA Février 2020 45


Gestion des Exceptions

Servlet

objet exception
lancé par la servlet génère une
réponse HTML

intercepté (catch) et
traité par le conteneur
(Tomcat) qui a fait
l'appel à doGet
<!DOCTYPE html>
<html>
<head>
La logique de traitement de l'exception spécifique au conteneur de
<title>Apache Tomcat/8.5.11 –

...
Rapport d''erreur</title> servlets, selon le conteneur (Tomcat, Jetty, GlassFish, WildFly…)
</html>
une réponse HTML d'erreur différente peut être obtenue.

Limitations de ce type de réponse:


• peut être utile en phase de développement, mais de peu de valeur pour un utilisateur final
• expose des détails de l'application et du serveur qui n'ont aucun sens qui ont peu d'intérêt pour un utilisateur
• pas très bon non plus d'un point de vue sécurité

Possibilité d'adapter ce comportement aux besoins de l'application


 Servlets de Gestion des Exceptions et Erreurs (Exception and Error Handler servlets)

© Philippe GENOUD UGA Février 2020 46


Gestion des exceptions
 Servlets de Gestion des Exceptions et Erreurs (Exception and Error Handler servlets)
 rôle: gérer les exceptions et erreur levées par l'application et envoyer à l'utilisateur une réponse HTML
adaptée.
 message d'erreur approprié, lien vers la page d'accueil de l'application…

 invoquées automatiquement par le conteneurs en fonction du type de l'exception ou de l'erreur


 règles d'invocation définies dans le fichier de déploiement de l'application: web.xml

 possibilité d'accéder à un certain nombre d'informations pouvant être utiles et positionnées comme
attributs de la requête par le conteneur.

Nom de l'attribut Valeur


javax.servlet.error.exception Référence de l'objet exception
javax.servlet.error.servlet_name Nom complet de la classe de la servlet ayant lancé l'exception
javax.servlet.error.request_uri URI ayant provoqué l'exception ou l'erreur
javax.servlet.error.status_code Code HTTP de statut de la réponse.
toujours 500 (“Internal Server Error”) pour les exceptions

© Philippe GENOUD UGA Février 2020 47


 exemple de servlet de gestion
des Exceptions et Erreurs.

© Philippe GENOUD UGA Février 2020 48


Gestion des exceptions
 le fichier de déploiement web.xml XML Schema Description (XSD)
"grammaire" du langage XML utilisé pour les
fichier de déploiement d'application web JEE7
 défini les balises et attributs autorisées

gestionnaire global: utilisé si aucun des mapping error-code ou error-


type ne permet de traiter l'erreur ou l'exception

localhost:8080/TestServletException/mauvaiseURI

associe un gestionnaire à type


d'erreur particulier

associe un gestionnaire à type


d'exception particulier
http://localhost:8080/TestServletException/testException?nb=5&nom=WORLD

© Philippe GENOUD UGA Février 2020 49


Cookies
Cookie (témoin de connexion) : petit élément d'information envoyé depuis un serveur vers un client HTTP et que ce
dernier retourne lors de chaque interrogation du même serveur HTTP sous certaines conditions. Les cookies sont stockée
localement sur le poste client.

 classe javax.servlet.http.Cookie

requête HTTP
Cookie
+Cookie(String name, String value)
+getName():String  récupérer un cookie
+getMaxAge():int
+getValue():String
 via l'objet HttpServletRequest
+getDomain():String  Cookie[] getCookies()
...
+setValue(String v):void
+setMaxAge(int expiry):void
+setdomain(String domain):void
...

réponse HTTP
une fois le cookie créé, son nom ne peut plus être
changé (pas de méthode setName())
 déposer un cookie
 via l'objet HttpServletResponse
 void addCookie(Cookie c)

© Philippe GENOUD UGA Février 2020 50


Sessions
 De nombreuses applications nécessitent de relier entre elles une série de requêtes issues
d'un même client
 ex : application de E-commerce doit sauvegarder l'état du panier du client
 Session :
 Période de temps correspondant à navigation continue d'un utilisateur sur un site
 HTTP étant sans état (Stateless) c'est de la responsabilité des applications web de
conserver un tel état, i.e de gérer les sessions :
 Identifier l'instant où un nouvel utilisateur accède à une des pages du site
 Conserver des informations sur l'utilisateur jusqu'à ce qu'il quitte le site
 Cookies ≃ variables permettant de contrôler l'exécution de l'application Web. Mais …
 stockage côté client
 Possibilité de modifier les variables côté client
 DANGEREUX
 Les données liées aux sessions doivent rester côté serveur <<interface>> HttpSession
 seul l'identifiant de session transmis sous forme de cookie +getAttribute(name:String):Object
+getAttributeNames():Enumeration<String>
 en Java utilisation de l’interface : +getId():int
+invalidate():void
 javax.servlet.http.HttpSession +isNew():boolean
+setAttribute(name:String, o:Object):void
+setMaxInactiveInterval(interval:int):void

© Philippe GENOUD UGA Février 2020 51


utilisation de l'objet HttpSession
 Objet HttpSession
 pas de classe d'implémentation dans l'API JavaEE (HttpSession est une interface)
 classe d'implémentation dépend du conteneur web JEE (TomCat, Jetty, ….)
 instanciée par le conteneur

 dans le code des servlets on n'utilise que l'interface

 associé à l'objet HttpServletRequest qui permet de le récupérer ou de le créer


 logique : car identifiant de session transmis dans requête http (cookie ou paramètre de requête)

 Obtenir une session :


 HttpSession session = request.getSession() ;
 Récupération de la session associée à la requête

 Création d'une nouvelle session si elle n’existe pas

 HttpSession session = request.getSession(boolean create) ;


 si une session est associée à la requête récupération de celle-ci

 sinon (il n'existe pas de session)


– si create == true, création d'une nouvelle session et récupération de celle-ci
– si create == false  null
 boolean isNew()
 true si le serveur a crée une nouvelle session (et que l'identifiant n'a pas encore été transmis au
client)

© Philippe GENOUD UGA Février 2020 52


utilisation de l'objet HttpSession
 Fin de session :
 l'application met volontairement fin à la session : void invalidate()
 destruction de la session et de tous les éléments qu'elle contient

 le serveur le fait automatiquement après une certaine durée d'inutilisation


 configuré dans le fichier de déploiement de l'application (web.xml)
– exemple
<session-config>
<session-timeout>10</session-timeout>
</session_config>
 configuré par l'application
– int getMaxInactiveInterval()
recupère la durée de vie (en seconde) de la session si elle est inutilisée
– void setMaxInactiveInterval(int interval)
fixe la durée de vie (en seconde) de la session si elle est inutilisée

© Philippe GENOUD UGA Février 2020 53


utilisation de l'objet HttpSession

 Sauvegarde d’objets :
 Association clé ⇔ instance : void setAttribute(String key, Object value)
 exemple :
HttpSession session = request.getSession();
String name= "Joe Moose";
session.setAttribute("nom", name);
session.setAttribute("couleur", new Color(222,114,14));
 Extraction d’objets :
 récupération d'un objet à partir de sa clé : Object getAttribute(String key)
 exemple :
HttpSession session = request.getSession();
String theName = (String) session.getAttribute("nom");
Color c = (Color) session.getAttribute("couleur");

© Philippe GENOUD UGA Février 2020 54


Contexte de l'application

 application constituée généralement de plusieurs ressources


 servlets, pages JSP (Java Server Pages), pages HTML, images …
 ces éléments sont regroupés par le serveur dans un conteneur : le contexte de l'application
 servlets, pages JSP
 informations de configuration (issues du fichier de déploiement web.xml ou des annotations des
servlets)
 informations déposées par les servlets ou JSP et partagées par tous
 tous les composants y on accès indépendamment des sessions utilisateur ("variables globales")

 attributs du contexte de l'application

 représenté par un objet instance de l'interface http.servlet.ServletContext

© Philippe GENOUD UGA Février 2020 55


Contexte de l'application
 obtention de l'objet ServletContext
 méthode ServletContext getServletContext() héritée de HttpServlet

 méthodes de l'objet ServletContext


 gestion des attributs , même principe que pour la session
 void setAttribute(String key, Object value)
déposer un attribut
 Object getAttribute(String key)
récupérer un attribut
 accès aux paramètres de configuration de l'application
 String getInitParameter(String name)

 paramètres déclarés dans le fichier de déploiement (web.xml)


– exemple
<context-param>
<param-name>admin-mail</param-name>
<param-value>Joe.Moose@yukon.org</param-value>
</context-param>

© Philippe GENOUD UGA Février 2020 56


Filtres
 Introduits à partir de la version 2.3 de l'API des servlets les filtres
permettent d'intercepter les requêtes et réponses des servlets
 possibilité d'ajouter un traitement
 avant que la requête ne soit reçue par une servlet

 avant que la réponse ne soit transmise au client

 Nombreuses utilisations des filtres :


 authentificiation
 redirection
 modification des entêtes
 cryptage des données
 contrôle des accès effectués par les clients
 journalisation des accès…

 Possibilité d'exécuter plusieurs filtre successivement sur le trajet d'une


requête ou d'une réponse HTTP

© Philippe GENOUD UGA Février 2020 57


Filtres
Pour toutes les JSP et Servlets de l'application ne faire le traitement
que si une session est présente et que l'objet client est présent

HttpSession session = request.getSession(false);

if (session == null || session.getAttribute("client") == null) {


request.getRequestDispatcher(
"/accueil.jsp").forward(request, response);
return;
}

Mettre en œuvre ce traitement pour toutes les jsp


et les servlets TransfertServlet et LogoutServlet

Pour mettre en place ce traitement facilement utiliser un filtre de servlets

Introduits à partir de la version 2.3 de l'API des servlets les filtres permettent
d'intercepter les requêtes et réponses des servlets

Nombreuses utilisations des filtres :

• authentificiation
• redirection
• modification des entêtes
• cryptage des données
•…

© Philippe GENOUD UGA Février 2020 58


Un filtre : classe Java qui implémente l'interface javax.servlet.Filter

request request
Servlet

response response

public class SimpleFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)


throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;


System.out.println("Dans SimpleFilter filtrage de la requete " + httpRequest.getRequestURL());
Appel au prochain objet (un
chain.doFilter (request, response); filtre ou la servlet) dans la
System.out.println ("Dans SimpleFilter filtrage chaîne...");
de la réponse de filtrage
}

...
}
© Philippe GENOUD UGA Février 2020 59
Filtres

avec JavaEE 6 possibilité


d'utiliser les annotations
Le déploiement des filtres s'effectue au travers du fichier web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" ...>

<!– Definition des filtres présents dans l'application Web -->


<filter>
<filter-name>SimpleFilter</filter-name>
<filter-class>bima.filters.SimpleFilter</filter-class>
</filter>
...

<!– association des filtres à des servlets ou des urls -->


<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-– Définition des servlets -->


<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>bima.controler.LoginServlet</servlet-class>
</servlet>
...
<!– servlets mappings -->
...
</web-app>

© Philippe GENOUD UGA Février 2020 60


Plusieurs filtres peuvent être définis et appliqués à la même URL.
Chaînage effectué par appel à chain.doFilter (request, response);
Filtres
request request request request

MaServlet

response response response response


Filtre1 Filtre2 Filtre3

public class Filtre1Class implements Filter {


<!– Definition des filtres présents -->
public void doFilter(ServletRequest request, <filter>
ServletResponse response, FilterChain chain) <filter-name>Filtre1</filter-name>
throws IOException, ServletException { <filter-class>Filtre1Class</filter-class>
</filter>
System.out.println("Dans Filtre1 filtrage de la requete" ); <filter>
chain.doFilter (request, response); <filter-name>Filtre3</filter-name>
System.out.println ("Dans Filtre1 filtrage de la réponse"); <filter-class>Filtre3Class</filter-class>
public class Filtre2Class implements Filter { </filter>
}
<filter>
public void doFilter(ServletRequest request, <filter-name>Filtre2</filter-name>
...
ServletResponse response, FilterChain chain) <filter-class>Filtre2Class</filter-class>
}
throws IOException, ServletException { </filter>

System.out.println("Dans Filtre2 filtrage de la requete" );


chain.doFilter (request, response); <!– association des filtres à des urls -->
System.out.println ("Dans Filtre2 filtrage de la réponse"); <filter-mapping>
public class Filtre3Class implements Filter {
} <filter-name>Filtre1</filter-name> L'ordre
public void doFilter(ServletRequest request, <url-pattern>/uneURL</url-pattern> d'exécution est
... </filter-mapping>
}
ServletResponse response, FilterChain chain)
throws IOException, ServletException { <filter-mapping>
défini par l'ordre
<filter-name>Filtre2</filter-name> des mappings
System.out.println("Dans Filtre3 filtrage de la requete" ); <url-pattern>/uneURL</url-pattern> dans le
</filter-mapping>
chain.doFilter (request, response);
System.out.println ("Dans Filtre3 filtrage de la
Dans Filtre1 réponse");
filtrage de la requete <filter-mapping>
descripteur de
} Dans Filtre2 filtrage de la requete <filter-name>Filtre3</filter-name> déploiement
Dans Filtre3 filtrage de la requete <url-pattern>/uneURL</url-pattern>
... Dans Filtre3 filtrage de la réponse </filter-mapping>
} Dans Filtre2 filtrage de la réponse
Dans Filtre1 filtrage de la réponse
© Philippe GENOUD UGA Février 2020 61
Filtres
Un filtre peut "courcircuiter" la chaîne de
filtrage pour effectuer des aiguillages
MaServlet
request

response
<!– Definition des filtres présents -->
<filter> FiltreAiguilleur
<filter-name>FiltreAiguilleur</filter-name> UnPageJSP
<filter-class>UnFiltre</filter-class>
</filter>

<!– association des filtres à des urls -->


<filter-mapping>
<filter-name>FiltreAiguilleur</filter-name>
<url-pattern>/maServlet</url-pattern>
</filter-mapping>
public class UnFiltre implements Filter {

public void doFilter(ServletRequest request,


ServletResponse response, FilterChain chain)
throws IOException, ServletException {

if (condition) {
RequestDispatcher rd = request.getRequestDispatcher("/UnePageJSP.jsp");
rd.dispatch(request,respeonse);
}
else
chain.doFilter (request, response);
}

...
}

© Philippe GENOUD UGA Février 2020 62


Par défaut le filtre n'est appliqué qu'aux requêtes issues directement du client mais pas aux
requêtes forwardées
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" ...>
public class Servlet1 extends HttpServlet {
<!– Definition des filtres présents dans l'application Web -->
protected void doGet(HttpServletRequest request, HttpServletResponse response) <filter>
throws ServletException, IOException { <filter-name>Filtre1</filter-name>
System.out.println("Dans servlet 1"); <filter-class>filters.Filter1</filter-class>
request.getRequestDispatcher("/Servlet2").forward(request,response); </filter>
}
<filter>
… <filter-name>Filtre2</filter-name>
} <filter-class>filters.Filter2</filter-class>
</filter>
public class Servlet2 extends HttpServlet {
<!– association des filtres à des servlets ou des urls -->
protected void doGet(HttpServletRequest request, HttpServletResponse response) <filter-mapping>
throws ServletException, IOException { <filter-name>Filtre1</filter-name>
System.out.println("Dans servlet 2"); <url-pattern>/Servlet1</url-pattern>
response.setContentType("text/html;charset=UTF-8"); </filter-mapping>
PrintWriter out = response.getWriter();
out.println("<html>"); <filter-mapping>
out.println("<head>"); <filter-name>Filtre2</filter-name>
out.println("<title>Servlet Servlet2</title>"); <url-pattern>/Servlet2</url-pattern>
out.println("</head>"); </filter-mapping>
out.println("<body>");
out.println("<h1>Servlet Servlet2 at " + request.getContextPath () + "</h1>");
out.println("</body>"); <!-– Définition des servlets -->
out.println("</html>"); <servlet>
out.close(); <servlet-name>Servlet1</servlet-name>
} <servlet-class>servlet.Servlet1</servlet-class>
Dans Filtre1 filtrage de la requete http://localhost:8090/Test/Servlet1 </servlet>
… Dans servlet 1 …
} Dans servlet 2 <!– servlets mappings -->
Dans Filtre1 filtrage de réponse ...
</web-app>

request request
Servlet1
request
forward Servlet2
response
response response
Filtre1

© Philippe GENOUD UGA Février 2020 63


Filtres
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" ...>

Depuis version 2.4 des servlets possibilité de


<!– Definition des filtres présents dans l'application Web -->
<filter>
contrôler dans le fichier de déploiement <filter-name>Filtre1</filter-name>
<filter-class>filters.Filter1</filter-class>
Dans quel "contexte de dispatching" les </filter>
filtres doivent être invoqués <filter>
<filter-name>Filtre2</filter-name>

Filtre appliqué :
<filter-class>filters.Filter2</filter-class>
</filter>
- au requêtes issues du client
- au requêtes issues d'un forward <!– association des filtres à des servlets ou des urls -->
<filter-mapping>
<filter-name>Filtre1</filter-name>
<url-pattern>/Servlet1</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<dispatcher>FORWARD</dispatcher>

<filter-mapping>
<filter-name>Filtre2</filter-name>
<url-pattern>/Servlet2</url-pattern>
</filter-mapping>

<!-– Définition des servlets -->


<servlet>
Dans Filtre1 filtrage de la requete http://localhost:8090/Test/Servlet1 <servlet-name>Servlet1</servlet-name>
Dans servlet 1 <servlet-class>servlet.Servlet1</servlet-class>
Dans Filtre2 filtrage de la requete http://localhost:8090/Test/Servlet2 </servlet>
Dans servlet 2 …
Dans Filtre2 filtrage de la réponse <!– servlets mappings -->
Dans Filtre1 filtrage de réponse ...
</web-app>

request request
Servlet1
request
request
forward Servlet2
response
response
response response
Filtre1 Filtre2

© Philippe GENOUD UGA Février 2020


64 64

Vous aimerez peut-être aussi