Le filtre Java Servlet est utilisé pour intercepter la demande du client et effectuer un prétraitement. Il peut également intercepter la réponse et effectuer un post-traitement avant de l’envoyer au client dans l’application web. C’est le quatrième article de la série Tutoriel sur les applications web, vous voudrez peut-être consulter les articles précédents aussi.
Filtre Servlet
Dans cet article, nous allons nous pencher sur le filtre Servlet en Java. Nous examinerons divers usages du filtre servlet, comment créer un filtre et apprendre à l’utiliser avec une application web simple.
-
Exemple de filtre Servlet pour la journalisation et la validation de session
-
Pourquoi avons-nous des filtres Servlet ?
Dans le dernier article, nous avons appris comment nous pouvons gérer la session dans une application web et si nous voulons nous assurer qu’une ressource est accessible uniquement lorsque la session utilisateur est valide, nous pouvons y parvenir en utilisant les attributs de session servlet. L’approche est simple mais si nous avons beaucoup de servlets et de JSP, il deviendra difficile à maintenir en raison du code redondant. Si nous voulons changer le nom de l’attribut à l’avenir, nous devrons changer tous les endroits où nous avons l’authentification de session. C’est pourquoi nous avons un filtre servlet. Les filtres Servlet sont des composants java plug-and-play que nous pouvons utiliser pour intercepter et traiter les requêtes avant qu’elles ne soient envoyées aux servlets et les réponses après que le code servlet soit terminé et avant que le conteneur n’envoie la réponse au client. Certaines tâches courantes que nous pouvons effectuer avec les filtres servlet sont :
- Enregistrement des paramètres de requête dans des fichiers journaux.
- Authentification et autorisation des requêtes pour les ressources.
- Formatage du corps ou de l’en-tête de la requête avant de l’envoyer au servlet.
- Compression des données de réponse envoyées au client.
- Modification de la réponse en ajoutant des cookies, des informations d’en-tête, etc.
Comme je l’ai mentionné précédemment, les filtres servlet sont plug-and-play et configurés dans le descripteur de déploiement (fichier web.xml). Les servlets et les filtres sont tous deux inconscients les uns des autres et nous pouvons ajouter ou supprimer un filtre servlet simplement en éditant le fichier web.xml. Nous pouvons avoir plusieurs filtres pour une seule ressource et nous pouvons créer une chaîne de filtres pour une seule ressource dans web.xml. Nous pouvons créer un filtre Servlet en implémentant l’interface
javax.servlet.Filter
. -
Interface de filtre Servlet
L’interface de filtre Servlet est similaire à l’interface Servlet et nous devons l’implémenter pour créer notre propre filtre Servlet. L’interface de filtre Servlet contient des méthodes du cycle de vie d’un filtre et elle est gérée par le conteneur de servlet. Les méthodes du cycle de vie de l’interface de filtre Servlet sont les suivantes :
- void init(FilterConfig paramFilterConfig) – Lorsque le conteneur initialise le filtre, c’est la méthode qui est invoquée. Cette méthode n’est appelée qu’une fois dans le cycle de vie du filtre et nous devrions initialiser toutes les ressources dans cette méthode. FilterConfig est utilisé par le conteneur pour fournir des paramètres d’initialisation et un objet de contexte de servlet au filtre. Nous pouvons lever ServletException dans cette méthode.
- doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – C’est la méthode invoquée à chaque fois par le conteneur lorsqu’il doit appliquer un filtre à une ressource. Le conteneur fournit les références d’objet de demande et de réponse au filtre en tant qu’arguments. FilterChain est utilisé pour invoquer le filtre suivant dans la chaîne. C’est un excellent exemple du modèle de conception de chaîne de responsabilité.
- void destroy() – Lorsque le conteneur décharge l’instance du filtre, il invoque la méthode destroy(). C’est la méthode où nous pouvons fermer toutes les ressources ouvertes par le filtre. Cette méthode n’est appelée qu’une fois dans la vie du filtre.
-
Annotation Servlet WebFilter
javax.servlet.annotation.WebFilter
a été introduite dans Servlet 3.0 et nous pouvons utiliser cette annotation pour déclarer un filtre de servlet. Nous pouvons utiliser cette annotation pour définir des paramètres d’initialisation, le nom et la description du filtre, les servlets, les motifs d’URL et les types de répartiteurs pour appliquer le filtre. Si vous apportez fréquemment des modifications aux configurations du filtre, il est préférable d’utiliser web.xml car cela ne nécessitera pas de recompiler la classe de filtre. Lire: Tutoriel sur les annotations Java -
Configuration du filtre Servlet dans web.xml
Nous pouvons déclarer un filtre servlet dans web.xml comme ci-dessous.
<filter> <filter-name>RequestLoggingFilter</filter-name> <!-- obligatoire --> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- obligatoire --> <init-param> <!-- optionnel --> <param-name>test</param-name> <param-value>testValue</param-value> </init-param> </filter>
Nous pouvons mapper un filtre à des classes servlet ou à des url-patterns comme ci-dessous.
<filter-mapping> <filter-name>RequestLoggingFilter</filter-name> <!-- obligatoire --> <url-pattern>/*</url-pattern> <!-- soit url-pattern soit servlet-name est obligatoire --> <servlet-name>LoginServlet</servlet-name> <dispatcher>REQUEST</dispatcher> </filter-mapping>
Note : Lors de la création de la chaîne de filtres pour un servlet, le conteneur traite d’abord les url-patterns puis les servlet-names, donc si vous devez vous assurer que les filtres sont exécutés dans un ordre particulier, accordez une attention particulière lors de la définition du mapping du filtre. Les filtres servlet sont généralement utilisés pour les requêtes des clients mais parfois nous voulons appliquer des filtres avec le RequestDispatcher aussi, nous pouvons utiliser l’élément dispatcher dans ce cas, les valeurs possibles sont REQUEST, FORWARD, INCLUDE, ERROR et ASYNC. Si aucun dispatcher n’est défini, il s’applique uniquement aux requêtes des clients.
-
Exemple de filtre Servlet pour la journalisation et la validation de session
In our **servlet filter example**, we will create filters to log request cookies and parameters and validate session to all the resources except static HTMLs and LoginServlet because it will not have a session. We will create a dynamic web project **ServletFilterExample** whose project structure will look like the below image. [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Example-Project.png) login.html is the entry point of our application where the user will provide the login id and password for authentication. login.html code:
```
Login Page
```
LoginServlet is used to authenticate the request from the client for login.
```
package com.journaldev.servlet.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String userID = "admin";
private final String password = "password";
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// obtenir les paramètres de requête pour l'identifiant utilisateur et le mot de passe
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
if(userID.equals(user) && password.equals(pwd)){
HttpSession session = request.getSession();
session.setAttribute("user", "Pankaj");
// réglage de la session pour qu'elle expire dans 30 minutes
session.setMaxInactiveInterval(30*60);
Cookie userName = new Cookie("user", user);
userName.setMaxAge(30*60);
response.addCookie(userName);
response.sendRedirect("LoginSuccess.jsp");
}else{
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
PrintWriter out= response.getWriter();
out.println("Either user name or password is wrong.");
rd.include(request, response);
}
}
}
```
When the client is authenticated, it's forwarded to LoginSuccess.jsp LoginSuccess.jsp code:
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
Login Success Page
<%
// autoriser l'accès uniquement si la session existe
String user = (String) session.getAttribute("user");
String userName = null;
String sessionID = null;
Cookie[] cookies = request.getCookies();
if(cookies !=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("user")) userName = cookie.getValue();
if(cookie.getName().equals("JSESSIONID")) sessionID = cookie.getValue();
}
}
%>
Hi <%=userName %>, Login successful. Your Session ID=<%=sessionID %>
User=<%=user %>
Checkout Page
```
Notice that there is no session validation logic in the above JSP. It contains a link to another JSP page, CheckoutPage.jsp. CheckoutPage.jsp code:
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
Login Success Page
<%
String userName = null;
String sessionID = null;
Cookie[] cookies = request.getCookies();
if(cookies !=null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("user")) userName = cookie.getValue();
}
}
%>
Hi <%=userName %>, do the checkout.
```
LogoutServlet is invoked when a client clicks on the Logout button in any of the JSP pages.
```
package com.journaldev.servlet.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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;
/**
* Servlet implementation class LogoutServlet
*/
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("JSESSIONID")){
System.out.println("JSESSIONID="+cookie.getValue());
break;
}
}
}
// invalider la session si elle existe
HttpSession session = request.getSession(false);
System.out.println("User="+session.getAttribute("user"));
if(session != null){
session.invalidate();
}
response.sendRedirect("login.html");
}
}
```
Now we will create logging and authentication servlet filter classes.
```
package com.journaldev.servlet.filters;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* Servlet Filter implementation class RequestLoggingFilter
*/
@WebFilter("/RequestLoggingFilter")
public class RequestLoggingFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("RequestLoggingFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
Enumeration params = req.getParameterNames();
while(params.hasMoreElements()){
String name = params.nextElement();
String value = request.getParameter(name);
this.context.log(req.getRemoteAddr() + "::Request Params::{"+name+"="+value+"}");
}
Cookie[] cookies = req.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
this.context.log(req.getRemoteAddr() + "::Cookie::{"+cookie.getName()+","+cookie.getValue()+"}");
}
}
// passer la requête le long de la chaîne de filtres
chain.doFilter(request, response);
}
public void destroy() {
// nous pouvons fermer les ressources ici
}
}
```
```
package com.journaldev.servlet.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebFilter("/AuthenticationFilter")
public class AuthenticationFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("AuthenticationFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
this.context.log("Requested Resource::"+uri);
HttpSession session = req.getSession(false);
if(session == null && !(uri.endsWith("html") || uri.endsWith("LoginServlet"))){
this.context.log("Unauthorized access request");
res.sendRedirect("login.html");
}else{
// passer la requête le long de la chaîne de filtres
chain.doFilter(request, response);
}
}
public void destroy() {
// fermer les ressources ici
}
}
```
Notice that we are not authenticating any HTML page or LoginServlet. Now we will configure these filters mapping in the web.xml file.
```
ServletFilterExample
login.html
RequestLoggingFilter
com.journaldev.servlet.filters.RequestLoggingFilter
AuthenticationFilter
com.journaldev.servlet.filters.AuthenticationFilter
RequestLoggingFilter
/*
REQUEST
AuthenticationFilter
/*
```
Now when we will run our application, we will get response pages like below images. [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login.png) [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-Success.png) [](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Checkout.png) If you are not logged in and try to access any JSP page, you will be forwarded to the login page. In the server log file, you can see the logs written by servlet filters as well as servlets.
```
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginServlet
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/CheckoutPage.jsp
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LogoutServlet
JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56
User=Pankaj
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Aug 13, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
```
C’est tout pour le filtre de servlet en Java. C’est l’une des fonctionnalités importantes des applications web Java EE et nous devrions l’utiliser pour les tâches courantes effectuées par divers servlets. Dans les prochains articles, nous examinerons les auditeurs de servlets et les cookies. Mise à jour : Après avoir reçu de nombreuses demandes pour le projet téléchargeable, je l’ai attaché au message, téléchargez-le à partir du lien ci-dessous.
Télécharger le projet d’exemple de filtre de servlet
Consultez l’article suivant de la série sur Écouteur Servlet. Mise à jour Struts 2 utilise un filtre Servlet pour intercepter les requêtes clients et les transmettre aux classes d’action appropriées, appelées Intercepteurs Struts 2. Consultez Tutoriel pour débutants sur Struts 2.
Source:
https://www.digitalocean.com/community/tutorials/java-servlet-filter-example-tutorial