Mécanisme souvent méconnu, les listeners sont de simples classes Java qui seront automatiquement invoquées par le conteneur de JSP/Servlet lors du démarrage ou de l'arrêt de votre application. Comme les JSP ou les servlets, les listeners sont des composants, nous allons donc étudier leur contrat technique et leur mode de déploiement au travers d'un exemple simple : créer une connexion sur une base de données au démarrage de l'application et la fermer lors de l'arrêt de celle-ci

Contrat technique

Un listener est une simple classe Java qui implémente l'interface javax.servlet.ServletContextListener, et redéfinit donc les méthodes contextInitialized(ServletContextEvent) et contextDestroyed(ServletContextEvent) qui seront respectivement appelée lors du démarrage et de l'arrêt votre application. Notez que ces deux méthodes disposent d'un objet de type ServletContextEvent en paramètre. Cet objet est très précieux car il vous permet d'accéder au ServletContext (également appelé "scope" application) de votre application. Ainsi en stockant nos paramètres de connexion à la base de données dans le fichier web.xml, voilà comment nous pourrions créer notre connexion avant de la placer dans le scope application :

package com.juliencarette.listeners;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener{

        private Connection cnx=null;
        
        @Override
        public void contextInitialized(ServletContextEvent evt) {
                try {
                        ServletContext servletContext = evt.getServletContext();
                        String driver = servletContext.getInitParameter("jdbc.driver");
                        String url = servletContext.getInitParameter("jdbc.driver");
                        String login = servletContext.getInitParameter("jdbc.username");
                        String pwd = servletContext.getInitParameter("jdbc.password");
                        
                        Class.forName(driver);
                        cnx = DriverManager.getConnection(url, login, pwd);
                        servletContext.setAttribute("myCnx", cnx);
                
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
        
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvt) {
                try {
                        if(cnx!=null){
                                cnx.close();
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }

}

Déploiement

Comme pour les servlets, les listeners sont des classes, les classes compilées de vos listeners devront être placées dans le répertoire /WEB-INF/classes de votre application. Par ailleurs il vous faut les renseigner de la manière suivante dans le fichier web.xml de votre application.

<listener>
      <listener-class>com.juliencarette.listeners.MyListener</listener-class>
</listener>

Histoire de tester

Voilà votre listener est implémenté et correctement déployé, il sera donc pris en compte lors du prochain démarrage de votre application. Histoire de tester nous vous proposons d'implémenter la jsp suivante pour vérifié qu'on utilise toujours la même instance pour la connexion.

<%@page import="java.sql.Connection"%>

<% 
Connection cnx = (Connection)application.getAttribute("myCnx");
out.println(cnx.toString());
%>