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 HttpSessionListener
zou 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:
- Hoe om eenvoudig “wie is” te implementeren
online” in Grails of Java-toepassing
? - JSF: Hoe maak je een ongeldig
gebruikerssessie wanneer hij tweemaal inlogt met
dezelfde referenties
Ik heb de klasse SessionData
aangepast om HttpSessionBindingListener
te 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 SessionData
netjes 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 HttpSession
te 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 ServletContextListener
te 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:
- Hoe vind je
HttpSession
door jsessionid? - Hoe te vinden aantal actieve sessies per IP?
- Hoe om te controleren Wie is er online?
- Hoe maak je een andere sessie ongeldig wanneer een gebruiker twee keer is ingelogd?
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