10. Listeners

10.1. Introduction

Comme son nom le laisse supposer, un objet listener est un objet qui écoute certains événements dans une application. Lorsque l'événement qu'il écoute se déclenche, alors ce listener s'active : en général, une de ses méthodes particulière est invoquée, avec en paramètre un objet portant les informations sur cet événement. Le principe de fonctionnement est donc celui du callback : en tant que développeur d'application web, on enregistre des listeners auprès du serveur d'application. Ces objets doivent implémenter des interfaces standard, fournies par l'API Servlet, et être déclarés dans le descripteur d'une application web : le fichier web.xml.

10.2. Événements de l'API Servlet

Les événements définis par l'API Servlet sont au nombre de sept :
  • Trois événements concernent l'ajout ou le retrait d'un attribut sur le contexte, la session ou une requête : ServletContextEvent, HttpSessionEvent et ServletRequestEvent.
  • Deux événements sont associés à la création ou à la destruction du contexte, ou d'une requête : ServletContextEvent et ServletRequestEvent.
  • Un événement est associé au cycle de vie d'une session : HttpSessionEvent. Cet événement est utilisé par deux listeners : HttpSessionListener et HttpSessionActivationListener. Ces deux listeners sont associés au cycle de vie particulier des sessions, que nous allons voir dans la suite.
  • Un dernier événement permet de signaler à un objet qu'il a été ajouté à une session, ou qu'il va en être retiré : HttpSessionBindingEvent.

10.3. Ajout ou retrait d'un attribut

10.3.1. Interfaces listener

Les trois interfaces que l'on peut implémenter sont ServletContextAttributeListener, ServletRequestAttributeListener et HttpSessionAttributeListener. Ces trois interfaces exposent les trois mêmes méthodes :
  • attributeAdded() : appelée lorsqu'un attribut est ajouté au contexte considéré ;
  • attributeRemoved() : appelé lorsqu'un attribut est retiré du contexte considéré ;
  • attributeReplaced() : appelé lorsqu'un attribut a été remplacé par un autre.
Ces trois méthodes callback sont appelées une fois que l'événement d'ajout, de retrait, ou de remplacement a été effectué.

10.3.2. Objets événement associés

Ces trois méthodes prennent des paramètres différents en fonction du contexte, qui sont les événements que nous avons vus. Ces objets exposent tous les trois les même méthodes :
  • getName() : le nom de l'attribut concerné ;
  • getValue() : la valeur de l'attribut concerné.
L'objet HttpSessionBindingEvent, utilisé pour signaler à un objet qu'il a été ajouté ou retiré d'une session expose en plus une méthode getSession().

10.4. Création et destruction d'un contexte

Chaque contexte possède son interface listener .

10.4.1. Contexte de l'application

Le listener de création et destruction de l'application web doit implémenter l'interface ServletContextListener. Cette interface expose deux méthodes : contextInitialized() et contextDestroyed(). Ces deux méthodes sont invoquées avant toute invoquation de filtre ou de servlet, et après l'appel à toutes les méthodes destroy() des filtres et servlets de cette application, respectivement. Elles prennent en paramètre le même objet, de type ServletContextEvent. Cet objet expose une unique méthode : getServletContext(), qui retourne l'objet ServletContext. Cet objet modèlise l'application web proprement dite.

10.4.2. Contexte de la requête

Le listener de ce contexte implémente l'interface ServletRequestListener. Elle expose deux méthodes : requestInitialized() et requestDestroyed(). Ces deux méthodes prennent en paramètre le même objet, instance de ServletRequestEvent. Cet objet permet d'accèder au contexte de l'application web par la méthode getServletContext(), et à l'objet requête par la méthode getServletRequest().

10.4.3. Contexte de la session

La session a un cycle de vie un peu particulier, du fait de sa nature. Rappelons tout d'abord qu'une application web n'a pas nécessairement besoin de la notion de session. Une session devient nécessaire lorsque l'on a besoin de reconnaître un client donné d'une requête à l'autre. Dans ce cas, une session est créée lors de la première requête de ce client. Cette session a une durée de vie, au-delà de laquelle elle est détruite. Cette durée de vie peut être plus ou moins longue : de quelques heures à plusieurs mois. Si les requêtes d'une même session se succèdent rapidement, alors cette session sera probablement conservée en mémoire. Si le client reste plusieurs heures sans revenir sur le site, et que le site choisit de conserver tout de même sa session, celle-ci sera probablement déchargée de la mémoire, et conservée sur un support persistant, probablement une base de données. On voit que quatre types d'événements peuvent alors exister pour une session :
  • La création : elle intervient lors de la première requête.
  • La destruction : elle peut ne jamais arriver, ou au bout d'un temps très long.
  • La passivation : c'est ce qui se passe lorsqu'une session est déplacée de la mémoire vers un espace de stockage persistant. La session n'est pas détruite, elle passe dans un état de type "inactif".
  • L'activation : ce qui se passe lorsqu'un client revient après une longue période d'absence. Sa session est rechargée de l'espace de stockage persistant vers la mémoire.
Notons que la passivation d'une session peu intervenir en environnement clusterisé, lorsqu'une session doit passer d'un nœud du cluster à un autre. Ces quatre événements sont gérés par deux interfaces.
  • HttpSessionListener : expose les méthodes sessionCreated() et sessionDestroyed(), qui prennent en paramètre un objet HttpSessionEvent.
  • HttpSessionActivationListener : expose les méthodes sessionDidActivate() et sessionWillPassivate(). Ces deux méthodes prennent en paramètre le même objet HttpSessionEvent.
L'objet HttpSessionEvent n'expose qu'une unique méthode : getSession(), qui retourne la session concernée.

10.5. Notification d'un objet attaché à un contexte

Enfin, un objet peut être notifié du fait qu'il a été ajouté à une session. Il doit pour cela implémenter l'interface HttpSessionBindingListener. Cette interface expose deux méthodes :
  • valueBound(HttpSessionBindingEvent) : appelée lorsque l'objet est attaché à une session ;
  • valueUnbound(HttpSessionBindingEvent) : appelée lorsque l'objet est détachée de la session.
Ces deux méthodes reçoivent en paramètre un objet de type HttpSessionBindingEvent. Cet événement expose les deux méthodes classiques getName() et getValue(). Il expose également getSession(), qui retourne la session à laquelle cet objet est attaché, ou de laquelle il est détaché.

10.6. Déclaration d'un listener dans une application web

Tous les listeners que nous avons vu doivent être déclarés dans le fichier web.xml.

Exemple 24. Déclaration de deux listeners dans web.xml

 <listener>
    <listener-class>
      org.paumard.cours.servlet.listener.ExampleSessionListener
    </listener-class>
  </listener>
  <listener>
     <listener-class>
       org.paumard.cours.servlet.listener.ExampleContextListener
     </listener-class>
 </listener>

Java servlet et JSP
Retour au blog Java le soir
Cours & Tutoriaux
Table des matières
Introduction
1. Position de l'API Servlet
2. Présentation
Présentation de Tomcat
1. Un peu d'histoire
2. Organisation des répertoires de Tomcat
2.1. Répertoire bin
2.2. Répertoire conf
2.3. Répertoire lib
2.4. Répertoire log
2.5. Répertoire temp
2.6. Répertoire webapp
2.7. Répertoire work
3. Lancement de Tomcat
3.1. Lancement par défaut
3.2. Accéder à l'administration de Tomcat
3.3. Plusieurs instances de Tomcat
4. Configuration de Tomcat
4.1. Introduction
4.2. Élément Server
4.3. Élément Service
4.4. Élément Connector
4.5. Élément Engine
4.6. Élément Host
4.7. Élément Context
4.8. Élément GlobalNamingResources
4.9. Élément Realm
4.10. Élément Valve
5. Définition et chargement des applications web
5.1. Introduction
5.2. Prise en compte des éléments Context
5.3. Chargement et mise à jour à chaud
6. Utilisation de Tomcat avec Apache
API Servlet
1. Introduction
2. Une première servlet
2.1. Le code
2.2. Création de l'application web
2.3. Déploiement dans Tomcat
3. Concepts, cycle de vie
3.1. Requête
3.2. Réponse
3.3. Session
3.4. Application web
3.5. Contexte d'exécution
3.6. Cycle de vie
3.7. Filtre
4. Présentation générale de l'API
4.1. Introduction
4.2. Interfaces disponibles
5. Notion de servlet
5.1. Interfaces servlet
5.2. Cycle de vie d'une servlet
5.3. Paramètres d'initialisation d'une servlet
6. Notion de requête
6.1. Accès aux paramètres d'une requête
6.2. Accès aux éléments de l'en-tête HTTP
6.3. Accès aux éléments de l'URL
6.4. Accès aux paramètres du client
6.5. Accès aux informations de sécurité
6.6. Accès à la session, au contexte et aux informations d'initialisation
7. Notion de réponse
7.1. Contrôle du buffer de sortie
7.2. Contrôle de la réponse HTTP
8. Notion de session HTTP
9. Redirection ou inclusion d'une ressource
10. Listeners
10.1. Introduction
10.2. Événements de l'API Servlet
10.3. Ajout ou retrait d'un attribut
10.4. Création et destruction d'un contexte
10.5. Notification d'un objet attaché à un contexte
10.6. Déclaration d'un listener dans une application web
11. Connexion à une base
11.1. Introduction
11.2. Connexion manuelle
11.3. Connexion par utilisation de source de données
Filtrage
1. Filtrage de servlets
2. Mise en place d'un filtre
2.1. Écriture d'un filtre
2.2. Déclaration du filtrage
3. Filtrage d'une requête
4. Filtrage d'une réponse
4.1. Fonctionnement de ce filtrage
Java Server Pages
1. Introduction
2. Un premier exemple
2.1. Une première JSP statique
2.2. Une première JSP dynamique
2.3. Fonctionnement interne des JSP
3. JSP scriplet
3.1. Les expressions
3.2. Les déclarations
3.3. Variables prédéfinies
3.4. Scriplet de directives
4. Utilisation de beans
4.1. Introduction
4.2. Déclaration d'un bean existant
4.3. Création d'un nouveau bean
4.4. Utilisation des propriétés d'un bean
5. Inclure un contenu externe dans une JSP
5.1. Introduction
5.2. Inclusion au lancement de l'application
5.3. Inclusion au traitement de la requête
6. Utilisation de bibliothèques de tags
6.1. Introduction
6.2. Bibliothèque core
7. Internationalisation
7.1. Notion de bundle
7.2. Internationalisation de pages JSP
Projet exemple
1. Présentation du projet