web-dev-qa-db-fra.com

Comment obtenir une liste de tous les objets HttpSession dans une application Web?

Disons que j'ai une application Web Java en cours d'exécution avec 0 ou plusieurs objets HttpSession valides qui lui sont associés. Je veux un moyen d'accéder à la liste actuelle des objets HttpSession valides. Je pensais que je pouvais implémenter un HttpSessionListener et l'utiliser pour ajouter à une liste de valeurs d'ID de session qui sont stockées dans un attribut de portée d'application, mais je suis sur le point de mettre à jour la liste en tant que sessions sont invalidés et qui sait quoi d'autre.

Avant de commencer à préparer ma propre solution, j'ai pensé que je devrais poser la question:
L'API de servlet fournit-elle des moyens d'accéder à la liste complète des objets de session non invalides?

J'utilise Tomcat 6.x comme conteneur d'application Web et la bibliothèque MyFaces 1.2.x (JSF).

[~ # ~] solution [~ # ~]
J'ai suivi une approche similaire à ce que BalusC a discuté dans ces questions existantes:

J'ai modifié par la classe SessionData pour implémenter HttpSessionBindingListener. Lorsqu'un événement de liaison se produit, l'objet s'ajoute ou se supprime de l'ensemble de tous les objets SessionData.

@Override
public void valueBound(HttpSessionBindingEvent event) { 
    // Get my custom application-scoped attribute
    ApplicationData applicationData = getApplicationData();
    // Get the set of all SessionData objects and add myself to it
    Set<SessionData> activeSessions = applicationData.getActiveSessions();
    if (!activeSessions.contains(this)) {
        activeSessions.add(this);
    }
}

@Override
public void valueUnbound(HttpSessionBindingEvent event) {
    HttpSession session = event.getSession();
    ApplicationData applicationData = getApplicationData();
    Set<SessionData> activeSessions = applicationData.getActiveSessions();
    if (activeSessions.contains(this)) {
        activeSessions.remove(this);
    }
}

La seule chose qui continue de m'énerver, c'est ce qui se passe au redémarrage de Tomcat. À moins que Tomcat n'ait été correctement configuré pour NE PAS sérialiser les sessions sur le disque, il le fera. Lorsque Tomcat redémarre, les objets HttpSession (et les objets SessionData avec eux) sont désérialisés et les sessions sont rendues valides à nouveau. Cependant, la sérialisation/désérialisation contourne totalement les événements d'écoute HttpSession, donc je n'ai pas la possibilité de remettre gracieusement la référence désérialisée vers SessionData dans mon ensemble d'objets géré après le redémarrage.

Je n'ai aucun contrôle sur la configuration de production de Tomcat dans l'organisation de mon client, je ne peux donc pas supposer que cela se fera comme je m'y attendais.

Ma solution consiste à comparer l'heure de création de HttpSession avec l'heure de démarrage de l'application lorsqu'une demande est reçue. Si la session a été créée avant l'heure de démarrage de l'application, j'appelle invalidate() et l'utilisateur est envoyé vers une page d'erreur/d'avertissement avec une explication de ce qui s'est passé.

J'obtiens l'heure de démarrage de l'application en implémentant un ServletContextListener et en stockant l'heure actuelle dans un objet de portée d'application à partir de la méthode contextInitialized() de mon écouteur.

49
Jim Tough

Non, l'API Servlet ne fournit aucun moyen. Vous devez vraiment les saisir tous à l'aide d'un HttpSessionListener. Vous pouvez trouver plusieurs exemples dans les réponses suivantes:

46
BalusC

Il n'y a pas de voie simple. Cela dépend du déploiement. Ci-dessus échouera une fois que vous aurez décidé d'introduire un déploiement distribué et un équilibrage de charge.

9
gertas

Pas vraiment une réponse, mais au bon vieux temps il y avait "javax.servlet.http.HttpSessionContext", mais il a été supprimé à partir de la version 2.1, explicitement sans remplacement: https: //Tomcat.Apache. org/Tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSessionContext.html

1
Nathan Crause