HttpSessionListener: come gestire gli utenti on line in Java

Scopo di questo articolo è proporre una soluzione semplice ad una delle problematiche più comuni che riguarda un'applicazione web: mantenere la lista degli utenti on line.
Innanzitutto distinguiamo i concetti di HttpSession e ServletContext.
In un'applicazione J2EE, una sessione (tipicamente legata ad un'utente) è rappresentata dalla classe javax.servlet.http.HttpSession e fornisce un'associazione tra il client HTTP ed il web server. Un ServletContext è costituito da un gruppo di servlet, pagine JSP o altre pagine web che condividono tra di loro risorse e dati. Ogni Servlet Context corrisponde, in pratica (a partire dalle specifiche 2.1 sulle Servlet), all'intera applicazione web, al contrario della sessione le cui risorse sono disponibili solo all'interno della sessione stessa.

Pertanto, la lista degli utenti on line (ad esempio un HashMap con chiave = sessionId e valore = username), sarà conservata in ServletContext. Ciò implica che:
1. quando un utente effettua il login sull'applicazione web e viene instanziata una nuova sessione sul web server, aggiungeremo una entry alla lista degli utenti;
2. quando un utente effettua il logout dall'applicazione web oppure la sessione va in timeout e scade, rimuoveremo la relativa entry dalla lista.

Java mette a disposizione degli sviluppatori, un'utilissima interfaccia (un listener) javax.servlet.http.HttpSessionListener che viene notificata con degli eventi ogni volta che la lista delle sessioni attive in una web application subisce un cambiamento.

I metodi da implementare sono :
- void sessionCreated(HttpSessionEvent se) : notifica della creazione di una sessione
- void sessionDestroyed(HttpSessionEvent se) : notifica dell'invalidazione di una sessione

Ad esempio:

package example;

public class MyHttpSessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent event) {

/* AGGIUNGI QUI L'UTENTE LOGGATO,
ALLA COLLECTION CONSERVATA IN SERVLET CONTEXT */
}

public void sessionDestroyed(HttpSessionEvent event) {
/* RIMUOVI QUI L'UTENTE LOGGATO,
DALLA COLLECTION CONSERVATA IN SERVLET CONTEXT
...
(HashMap)
event.getSession().getServletContext().getAttribute("userList").remove(event.getSession().getSessionId());
*/

}
}


Per attivare il listener, è inoltre necessario aggiungere la seguente voce al file web.xml:

<listener>
<listener-class>
example.MyHttpSessionListener
</listener-class>
</listener>

Riferimenti:

- http://java.sun.com/products/servlet/2.1/api/javax.servlet.http.HttpSession.html
- http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpSessionListener.html
- http://www.mokabyte.it/2002/01/servlet23_2.htm