mika-el
3/28/2018 - 11:40 AM

Filtre

A propos du filtre:

  • Un filtre est un objet Java qui peut modifier les en-têtes et le contenu d'une requête ou d'une réponse. Il se positionne avant la servlet, et intervient donc en amont dans le cycle de traitement d'une requête par le serveur.
  • Il peut être associé à une ou plusieurs servlets.
  • Les filtres peuvent intervenir à la fois sur la requête entrante et sur la réponse émise.
  • Ils s'appliquent dans un ordre précis, en cascade.
  • Le filtre ne crée habituellement pas de réponse ; il se contente généralement d'appliquer d'éventuelles modifications à la paire requête / réponse existante.
  • Les servets et les filtres ne sont instancié qu'une fois au démarrage du serveur. Ces servlets et filtres sont donc stockées dans la mémoire du serveur, et réutilisées à chaque fois qu'une URL appelée correspond à la servlet associée à l'url-pattern défini dans le web.xml ou l'annotation.
  • Toutes les variables d'instance ne seront initialisées qu'une seule fois, lors de l'instanciation de la servlet ou du filtre. Les variables locales quant à elles sembleront réinitialisées à chaque nouvel appel.
  • Par conséquent, Ne jamais assigner de données issues des portées request ou session ou de données client dans des variables d'instance d'une servlet ou filtre, mais uniquement dans des variables déclarées localement dans ses méthodes. Sinon elles seront accessibles a tout les clients...

Voici une liste des actions les plus communes réalisables par un filtre:

  • Interroger une requête et agir en conséquence.
  • Empêcher la paire requête / réponse d'être transmise plus loin, autrement dit bloquer son cheminement dans l'application.
  • Modifier les en-têtes et le contenu de la requête courante.
  • Modifier les en-têtes et le contenu de la réponse courante.

Le filtre offre trois avantages majeurs, qui sont interdépendants :

  • Il permet de modifier de manière transparente un échange HTTP. En effet, il n'implique pas nécessairement la création d'une réponse, et peut se contenter de modifier la paire requête / réponse existante.
  • Tout comme la servlet, il est défini par un mapping, et peut ainsi être appliqué à plusieurs requêtes.
  • Plusieurs filtres peuvent être appliqués en cascade à la même requête.

C'est la combinaison de ces trois propriétés qui fait du filtre un composant parfaitement adapté à tous les traitements de masse, nécessitant d'être appliqués systématiquement à tout ou partie des pages d'une application. À titre d'exemple, on peut citer les usages suivants : l'authentification des visiteurs, la génération de logs, la conversion d'images, la compression de données ou encore le chiffrement de données.

Shéma:

Fonctionnement:

  • Le filtre doit implémenter l'interface Filter.
  • Il n'existe ici pas de classe fille à l'interface Filter.

Structure à vide d'une classe filtre

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 ExempleFilter implements Filter {
    public void init( FilterConfig config ) throws ServletException {
        // Cycle de vie du filtre
        // Lors de l'instanciation, la méthode init() est appelée par le conteneur.
        // Si vous souhaitez passer des paramètres d'initialisation au filtre, vous pouvez alors les récupérer depuis l'objet FilterConfig passé en argument à la méthode.
    }

    public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException {
        // La méthode qui va contenir les traitements effectués par le filtre.
        // Une fois les traitements appliqués, soit vous appelez la méthode doFilter() de l'objet FilterChain pour passer au filtre suivant dans la liste,
        // soit vous effectuez une redirection ou un forwarding pour changer la destination d'origine de la requête.
    }

    public void destroy() {
        // Cycle de vie du filtre
    }
}

Déclaration des filtres dans le fichier web.xml:

Tout comme une servlet, un filtre doit être déclaré dans le fichier web.xml de l'application pour être reconnu.
Si vous souhaitez qu'un filtre soit appliqué avant un autre, placez son mapping avant le mapping du second dans le fichier web.xml de votre application.

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    ...

    <filter>
        <filter-name>Exemple</filter-name>
        <filter-class>package.ExempleFilter</filter-class>
    </filter>
    <filter>
        <filter-name>SecondExemple</filter-name>
        <filter-class>package.SecondExempleFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>Exemple</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>SecondExemple</filter-name>
        <url-pattern>/page</url-pattern>
    </filter-mapping>

    ...
</web-app>

Appliquer un filtre à un forwarding ou à un include:

Un filtre ne se décleche par défaut que pour une requète HTTP. Un filtre peut s'appliquer à un forwarding ou à un include avec la balise <dispatcher>.

<filter-mapping>
    <filter-name>RestrictionFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>    
    <dispatcher>FORWARD</dispatcher> 
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>