Afin d'avoir une exemple parlant et facile à mettre en place, je vous propose de reprendre l'exemple que nous avons utilisé dans le chapitre sur les sessions…
Nous allons cependant ajouter des filtres à tout ceci :
- un filtre à la servlet récupérant les données du formulaire ;
- deux filtres à la servlet affichant les données mises en session.
connexion.jsp
Code : JSP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Connexion à l'application</title>
</head>
<body>
<form name="session" method="POST" action="session.do" />
<table>
<tr>
<td>Login : </td>
<td><input type="text" name="login" /> </td>
</tr>
<tr>
<td>Mot de passe : </td>
<td><input type="password" name="password" /> </td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><input type="submit" name="valider" /></td>
</tr>
</table>
</form>
</body>
</html>
|
TestFilter.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | package com.sdz.session;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class TestFilter extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("Traitement dans la servlet : " + this.getServletName() + ".");
//On récupère les identifiants et on les stocke dans notre objet de session
String login = req.getParameter("login");
String password = req.getParameter("password");
HttpSession session = req.getSession();
session.setAttribute("login", login);
session.setAttribute("password", password);
//Maintenant, nous allons utiliser cet objet dans une autre servlet
resp.sendRedirect(resp.encodeURL("result.do"));
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
|
ResultatFilter.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 | package com.sdz.session;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ResultatFilter extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("Traitement dans la servlet : " + this.getServletName() + ".");
HttpSession session = req.getSession();
PrintWriter out = resp.getWriter();
//On va rajouter un attribut s'il n'existe pas
//Et, s'il existe, on va l'incrémenter
Object increment = session.getAttribute("increment");
if(increment == null){
session.setAttribute("increment", new Integer(1));
}
else{
int value = ((Integer)increment).intValue();
session.setAttribute("increment", ++value);
}
//On affiche l'identifiant de session unique
out.println("<h2>Numéro de la session en cours : " + session.getId() + "</h2>");
//On parcourt maintenant le contenu de notre objet session
Enumeration e = session.getAttributeNames();
while(e.hasMoreElements()){
String key = (String)e.nextElement();
out.println("<p>Clé : " + key + " - Valeur : " + session.getAttribute(key) + "</p>");
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
|
FirstFilter.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | package com.sdz.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class FirstFilter implements Filter{
private FilterConfig config;
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Premier filtre.");
//C'est via cette instruction que les filtres suivants et la servlet seront invoqués
chain.doFilter(request, response);
System.out.println("Fin du premier filtre.\n");
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
|
SecondFilter.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | package com.sdz.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SecondFilter implements Filter{
private FilterConfig config;
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Second filtre.");
//C'est via cette instruction que les filtres suivants et la servlet seront invoqués
chain.doFilter(request, response);
System.out.println("Fin du second filtre.\n");
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
|
ThirdFilter.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | package com.sdz.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ThirdFilter implements Filter{
private FilterConfig config;
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Troisième filtre.");
//C'est via cette instruction que les filtres suivants et la servlet seront invoqués
chain.doFilter(request, response);
System.out.println("Fin du troisième filtre.");
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
}
|
web.xml
Code : XML 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 | <web-app>
<servlet>
<servlet-class>com.sdz.session.TestFilter</servlet-class>
<servlet-name>firstFilter</servlet-name>
</servlet>
<servlet>
<servlet-class>com.sdz.session.ResultatFilter</servlet-class>
<servlet-name>resultFilter</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>firstFilter</servlet-name>
<url-pattern>/session.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>resultFilter</servlet-name>
<url-pattern>/result.do</url-pattern>
</servlet-mapping>
<filter>
<filter-name>firstFilter</filter-name>
<filter-class>com.sdz.filter.FirstFilter</filter-class>
</filter>
<filter>
<filter-name>secondFilter</filter-name>
<filter-class>com.sdz.filter.SecondFilter</filter-class>
</filter>
<filter>
<filter-name>thirdFilter</filter-name>
<filter-class>com.sdz.filter.ThirdFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>firstFilter</filter-name>
<servlet-name>firstFilter</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/result.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>thirdFilter</filter-name>
<url-pattern>/result.do</url-pattern>
</filter-mapping>
</web-app>
|
L'affichage nous donne la même chose que dans le chapitre sur les sessions :
Après avoir validé le formulaire :
Et voici ce qui s'affiche dans la console d'Eclipse :
Vous constatez que les filtres sont bien invoqués et que la servlet est bien appelée pendant l'exécution de la méthode
doFilter(). Je vais vous expliquer ce que j'ai fait.
Les classes qui servent de filtres doivent implémenter l'interface
Filter et, par conséquent, redéfinir les méthodes de l'interface ; ça, vous l'aviez deviné, j'en suis sûr.
Dans la méthode
init(FilterConfig config), nous avons initialisé une variable d'instance que nous avons ajoutée à nos filtres. Ceci juste au cas où nous aurions besoin d'accéder aux informations véhiculées dans cet objet lorsque nous serons dans les méthodes
doFilter() ou
destroy(). Puis nous avons défini ce qui devait être fait dans les méthodes
doFilter() de chaque filtre en prenant soin d'invoquer la méthode
doFilter() de l'objet
FilterChain.
Si cette instruction est absente, la pile d'invocation est stoppée et, par conséquent, les filtres suivants (s'il y en a) et finalement la servlet ne seront JAMAIS appelés : donc, on se retrouve avec une page blanche… Essayez de commenter cette ligne de code et vous verrez !
Une fois que toutes les classes sont définies, il ne reste plus qu'à tout relier via le descripteur de déploiement (le fichier
web.xml). Ceci se fait grâce au bloc XML :
Code : XML | <filter>
<filter-name>nomDuFiltre</filter-name>
<filter-class>mon.package.MonFiltre</filter-class>
</filter>
|
Avec ce bloc, nous informons le conteneur qu'un filtre existe. Maintenant, avec ce bloc :
Code : XML | <filter-mapping>
<filter-name>nomDuFiltre</filter-name>
<servlet-name>nomDeLaServlet</servlet-name>
</filter-mapping>
|
ou celui-ci :
Code : XML | <filter-mapping>
<filter-name>nomDuFiltre</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
|
... nous définissons sur quel critère appliquer le (ou les) filtre(s) :
- sur un nom de servlet ;
- sur une page spécifique ou un sous-ensemble d'URL.
Qu'est-ce que tu veux dire par un sous-ensemble ?
Dans notre exemple utilisant un mapping d'URL, nous avons utilisé le critère
result.do, mais si nous avions mappé notre servlet avec un sous-nom, comme ceci :
Code : XML | <servlet-mapping>
<servlet-name>resultFilter</servlet-name>
<url-pattern>/RESULT/result.do</url-pattern>
</servlet-mapping>
|
... il nous serait alors possible d'ordonner au conteneur d'utiliser le filtre pour les servlets qui ont un chemin contenant le terme "
RESULT" :
Code : XML | <filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/RESULT/*</url-pattern>
</filter-mapping>
|
IMPORTANT : pour déterminer l'ordre des filtres, le conteneur prend en priorité les filtres mappés sur une URL. Une fois tous ces filtres trouvés et créés, le conteneur regarde ensuite les filtres éligibles via un nom de servlet.
Ça ressemble beaucoup aux blocs utilisés pour définir et mapper nos servlets…
N'est-ce pas ? C'est tellement vrai que vous avez aussi la possibilité d'affecter des paramètres d'initialisation à vos filtres, comme ceci :
Code : XML | <filter>
<filter-name>firstFilter</filter-name>
<filter-class>com.sdz.filter.FirstFilter</filter-class>
<init-param>
<param-name>param</param-name>
<param-value>Valeur du paramètre de filtre</param-value>
</init-param>
</filter>
|
Ces paramètres sont accessibles via l'objet
FilterConfig, objet que nous avons ajouté en variable d'instance, vous comprenez mieux pourquoi.
Vous aurez pu constater que je n'ai rien mis de particulier dans la méthode destroy(), ceci juste parce qu'il n'y avait rien de spécial à mettre… Pour être honnête, il y a fort à parier que vous ne vous en servirez jamais.