Nous venons de voir comment sont construites et initialisées nos servlets mais il reste une notion, que j'approfondirai au fil du tuto et que vous devez connaître.
En fait, votre conteneur favori vous permet d'écouter toute la phase de construction de nos servlets et plus encore.
Au long du chapitre précédent, nous avons vu comment définir des objets dans notre contexte mais, parce qu'il y a un mais, ceux-ci étaient définis par une servlet... Pas terrible !...
Comment vous y prendriez-vous pour initialiser un objet au lancement de l'application ? (Une connexion SQL par exemple, mais un bête objet fera l'affaire.)
En définissant cet attribut à notre contexte dans la méthode init()
de la servlet correspondant à notre page d'accueil.
Ah oui ? Et comment ferez-vous si je passe outre la page d'accueil, en saisissant une URL connue par exemple ?
Vous n'allez tout de même pas mettre cette instruction dans la méthode
init()
de toutes vos servlets !
Dans ces moments-là, la méthode
public static void main(String[] args)
vous manque réellement...
Avoir un endroit où on peut faire ce que l'on veut avant le réel démarrage de l'application.
Cependant, comme je vous le disais dans le chapitre précédent, les concepteurs de la technologie sont de gentils concepteurs :
ils vous ont donné le moyen d'initialiser des objets en dehors de toute servlet !
Et comment on fait ça ?
Avec de bons vieux événements, comme en programmation événementielle.
Durant toute la phase d'initialisation de notre application, le conteneur vous offre la possibilité d'écouter des événements afin de pouvoir faire des actions spécifiques à ce moment-là.
Bon : à partir de maintenant, tous les ZérOs qui ne savent pas comment les événements graphiques sont gérés en Java sont priés d'aller faire un tour sur le
tuto concernant le pattern observer !
Alors, le but du jeu est de pouvoir initialiser un objet avant qu'une seule servlet ne soit instanciée, ceci afin que ce qui est fait à ce moment (l'initialisation de l'application) puisse être utile à toute l'application.
Déjà, avec ma phrase, vous avez dû comprendre que l'événement que nous allons utiliser était attaché au contexte de notre application :
une seule chose est commune à l'application, le contexte.
Alors qui dit événement, dit interface à implémenter et, concernant le contexte, nous allons implémenter l'interface :
ServletContextListener.
Vous pouvez voir que cette interface nous donne la possibilité d'agir lors de la création du contexte ou lors de sa destruction.
Alors, vu que vous êtes friands d'exemples en tout genre, nous allons faire un test.
Nous allons faire une servlet qui appelle un attribut attaché à l'objet
ServletContext mais défini lors de la création dudit objet.
Pour faire ceci, nous allons avoir besoin :
- d'une servlet ;
- d'un objet servant à écouter l'événement ;
- d'un objet codé par nos soins.
J'ai fait un nouveau projet Tomcat et voici ce que j'y ai mis.
Un objet métier que vous avez déjà vu tout à l'heure, l'objet
ZColor.
Fichier ZColor.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13 | package com.sdz.test;
public class ZColor {
private String color = "";
public ZColor(String color){
this.color = color;
}
public String toString(){
return "COULEUR -> " + this.color;
}
}
|
Bon, vous connaissez cet objet, rien à ajouter à son sujet...

Maintenant, nous allons ajouter un objet
ZColor à notre contexte lors de sa création, ceci via la classe qui suit.
Il s'agit de notre classe qui va se charger d'écouter aux portes de notre conteneur... Une fois le contexte créé, la méthode
contextInitialized(ServletContextEvent event)
sera invoquée.
Fichier ContextListener.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | package com.sdz.test;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextListener implements ServletContextListener{
public void contextDestroyed(ServletContextEvent event) {}
public void contextInitialized(ServletContextEvent event) {
//Nous avons accès à l'objet ServletContext via l'objet ServletContextEvent
event.getServletContext().setAttribute("color", new ZColor("ROUGE"));
}
}
|
Maintenant, construisons une servlet qui aura pour rôle d'utiliser l'objet initialisé dans le contexte.
Fichier Index.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | package com.sdz.test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Index extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h2>Alors le contexte ?</h2>");
out.println("<p> " + getServletContext().getAttribute("color") + " </p>");
}
}
|
Voilà, nous avons presque terminé, nous n'avons plus qu'à configurer le contexte de notre application avec le fichier
web.xml.
Fichier web.xml
Code : XML 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | <web-app>
<servlet>
<servlet-class>com.sdz.test.Index</servlet-class>
<servlet-name>IndexServlet</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>IndexServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.sdz.test.ContextListener</listener-class>
</listener>
</web-app>
|
Oh ! Une nouveauté !
Oui, difficile de ne pas la voir...
Vous l'aurez compris, ces balises servent à dire à Tomcat que des classes sont à utiliser comme des
listeners.
Alors démarrez Tomcat et allez sur notre test, et voici ce que vous devriez avoir sous les yeux :
Pratique, n'est-ce pas ?
Vous venez de créer des attributs pour toute votre application sans ajouter une ligne de code à vos servlets.
En effet, en plus ce n'est pas trop dur...
Ah, je peux compliquer la tâche alors !