Hoe krijg ik een lijst van alle HttpSession-objecten in een webtoepassing?

Stel dat ik een draaiende op Java gebaseerde webtoepassing heb waaraan 0 of meer geldige HttpSession-objecten zijn gekoppeld. Ik wil een manier om toegang te krijgen tot de huidige lijst met geldige HttpSession-objecten. Ik dacht dat ik een HttpSessionListenerzou kunnen implementeren en deze zou kunnen gebruiken om toe te voegen aan een lijst met sessie-ID-waarden die zijn opgeslagen in een toepassingsgericht kenmerk, maar dan ben ik klaar om de lijst bij te werken omdat sessies ongeldig zijn en wie weet wat nog meer.

Voordat ik mijn eigen oplossing begon te bakken, dacht ik dat ik de vraag moest stellen:
Biedt de servlet-API een manier om toegang te krijgen tot de volledige lijst met niet-gevalideerde sessie-objecten?

Ik gebruik Tomcat 6.x als mijn webtoepassingscontainer en de MyFaces 1.2.x (JSF)-bibliotheek.

OPLOSSING
Ik volgde een benadering die vergelijkbaar is met wat BalusC besprak in deze bestaande vragen:

Ik heb de klasse SessionDataaangepast om HttpSessionBindingListenerte implementeren. Wanneer een bindingsgebeurtenis plaatsvindt, zal het object zichzelf toevoegen aan of verwijderen uit de set van alle SessionData-objecten.

@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);
    }
}

Het enige dat me blijft irriteren, is wat er gebeurt als Tomcat opnieuw wordt opgestart. Tenzij Tomcat correct is geconfigureerd om sessies NIET naar schijf te serialiseren, zal het dit doen. Wanneer Tomcat opnieuw opstart, worden de HttpSession-objecten (en de SessionData-objecten samen met hen) gedeserialiseerd en worden de sessies weer geldig gemaakt. De serialisatie/deserialisatie gaat echter volledig voorbij aan de HttpSession-listenergebeurtenissen, dus ik heb niet de mogelijkheid om de gedeserialiseerde verwijzing naar de SessionDatanetjes terug in mijn beheerde set objecten te plaatsen na de herstart.

Ik heb geen controle over de productieconfiguratie van Tomcat in de organisatie van mijn klant, dus ik kan er niet vanuit gaan dat het wordt gedaan zoals ik het verwacht.

Mijn tijdelijke oplossing is om de aanmaaktijd van HttpSessionte vergelijken met de opstarttijd van de toepassing wanneer een verzoek wordt ontvangen. Als de sessie is gemaakt vóór de opstarttijd van de toepassing, roep ik invalidate()aan en wordt de gebruiker naar een fout-/waarschuwingspagina gestuurd met een uitleg van wat er is gebeurd.

Ik krijg de opstarttijd van de toepassing door een ServletContextListenerte implementeren en de huidige tijd op te slaan in een object met toepassingsbereik vanuit de methode contextInitialized()van mijn luisteraar.


Antwoord 1, autoriteit 100%

Nee, de Servlet API biedt geen manier. Je moet ze echt allemaal te pakken krijgen met behulp van een HttpSessionListener. U kunt verschillende voorbeelden vinden in de volgende antwoorden:


Antwoord 2, autoriteit 19%

Er is geen directe manier. Het hangt af van de inzet. Het bovenstaande zal mislukken zodra u besluit om gedistribueerde implementatie en taakverdeling te introduceren.


Antwoord 3, autoriteit 2%

Niet echt een antwoord, maar in de goede oude tijd was er “javax.servlet.http.HttpSessionContext”, maar het werd verwijderd vanaf versie 2.1, expliciet zonder vervanging: https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/ servlet/http/HttpSessionContext.html

Other episodes