2010-09-22 19 views
48

Załóżmy, że mam działającą aplikację Java oparta na języku Java z 0 lub więcej poprawnymi obiektami HttpSession z nią powiązanymi. Chcę uzyskać dostęp do aktualnej listy ważnych obiektów HttpSession. Myślałem, że mogę zaimplementować HttpSessionListener i użyć go do dołączenia do listy wartości identyfikatora sesji, które są przechowywane w atrybucie o zasięgu aplikacji, ale wtedy jestem na bieżąco, aby zaktualizować listę, ponieważ sesje są unieważniane i kto wie co jeszcze.Jak uzyskać listę wszystkich obiektów HttpSession w aplikacji internetowej?

zanim zacznę pieczenia moje własne rozwiązanie pomyślałem, że powinienem zadać pytanie:
Czy API serwletów podać kilka sposobów na uzyskanie dostępu do pełnej listy niewyspecjalizowanych unieważnione obiektów sesji?

Używam Tomcat 6.x jako mojego kontenera aplikacji WWW i biblioteki MyFaces 1.2.x (JSF).

ROZWIĄZANIE
Śledziłem podejście podobne do tego, co BalusC omówione w tych istniejących pytań:

I zmodyfikowane przez SessionData klasy wdrożyć HttpSessionBindingListener. Gdy dojdzie do zdarzenia wiązania, obiekt albo doda, albo usunie się ze zbioru wszystkich obiektów 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); 
    } 
} 

Jedną rzeczą, która nadal mnie irytuje, jest to, co dzieje się po ponownym uruchomieniu Tomcata. O ile Tomcat nie został odpowiednio skonfigurowany do NIE serializowania sesji na dysku, zrobi to. Kiedy Tomcat ponownie się uruchamia, obiekty HttpSession (i obiekty SessionData wraz z nimi) są deserializowane i sesje są ponownie ważne. Jednak serializacja/deserializacja całkowicie omija zdarzenia detektora , więc nie mam możliwości z wdziękiem umieścić ponownie zserializowanego odwołania do SessionData w moim zarządzanym zestawie obiektów po ponownym uruchomieniu.

Nie mam żadnej kontroli nad konfiguracją produkcyjną Tomcata w organizacji mojego klienta, więc nie mogę zakładać, że będzie to wykonane tak, jak tego oczekuję.

Moje obejście polega na porównaniu czasu utworzenia HttpSession z czasem uruchomienia aplikacji po otrzymaniu żądania. Jeśli sesja została utworzona przed uruchomieniem aplikacji, wówczas zadzwonię pod numer invalidate(), a użytkownik zostanie wysłany na stronę błędu/ostrzeżenia z wyjaśnieniem, co się stało.

Dostaję czas uruchomienia aplikacji poprzez wdrożenie ServletContextListener i zapisanie bieżącego czasu wewnątrz obiektu o zasięgu aplikacji z metody contextInitialized() mojego detektora.

Odpowiedz

9

Nie ma prosty sposób do przodu. To zależy od wdrożenia. Powyżej nie powiedzie się, gdy zdecydujesz się wprowadzić wdrożenie rozproszone i równoważenie obciążenia.

+1

Moja aplikacja będzie miała ograniczoną liczbę użytkowników w sieci prywatnej, więc nie będę musiał obsługiwać dystrybucji rozproszonej. Zgadzam się jednak z twoim komentarzem. –

+0

Przypuszczam, że sposobem na zmianę tego (podobnie jak w przypadku upuszczania na dysku) byłoby uaktualnienie przez odbiornik udostępnionego magazynu danych (Redis, Memcached lub coś podobnego), który śledzi sesje. – Thilo

Powiązane problemy