2010-09-22 18 views
48

Digamos que tengo una aplicación web en ejecución con 0 o más objetos válidos HttpSession asociados. Quiero una forma de acceder a la lista actual de objetos válidos HttpSession. Estaba pensando que podría implementar un HttpSessionListener y usarlo para anexar a una lista de valores de id. De sesión que están almacenados en un atributo con ámbito de aplicación, pero luego estoy al acecho para actualizar la lista ya que las sesiones se invalidan y quién sabe Qué más.¿Cómo obtengo una lista de todos los objetos HttpSession en una aplicación web?

Antes de empezar a hornear mi propia solución que pensé que debería hacer la pregunta:
¿La API de servlets proporcionan unos medios de conseguir el acceso a la lista completa de los objetos no invalida la sesión?

Estoy utilizando Tomcat 6.x como contenedor de aplicaciones web y la biblioteca MyFaces 1.2.x (JSF).

SOLUCIÓN
he seguido un enfoque similar a lo que se discutió en BalusC estas preguntas existentes:

he modificado por SessionData clase para implementar HttpSessionBindingListener. Cuando ocurre un evento vinculante, el objeto se agregará o eliminará del conjunto de todos los objetos 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); 
    } 
} 

Lo único que continúa irritándome es lo que sucede cuando se reinicia Tomcat. A menos que Tomcat se haya configurado correctamente para NO serializar sesiones en el disco, lo hará. Cuando Tomcat se inicia de nuevo, los objetos HttpSession (y los objetos SessionData junto con ellos) se deserializan y las sesiones vuelven a ser válidas. Sin embargo, la serialización/deserialización evita totalmente los eventos de escucha HttpSession, por lo que no tengo la oportunidad de volver a poner correctamente la referencia deserializada en SessionData en mi Conjunto de objetos administrado después del reinicio.

No tengo ningún control sobre la configuración de producción de Tomcat en la organización de mi cliente, por lo que no puedo suponer que se hará de la manera que lo esperaba.

Mi solución consiste en comparar el tiempo de creación HttpSession con el tiempo de inicio de la aplicación cuando se recibe una solicitud. Si la sesión se creó antes del tiempo de inicio de la aplicación, entonces llamo al invalidate() y el usuario es enviado a una página de error/advertencia con una explicación de lo sucedido.

Obtengo el tiempo de inicio de la aplicación implementando un ServletContextListener y almacenando la hora actual dentro de un objeto con ámbito de aplicación desde el método contextInitialized() de mi escucha.

Respuesta

9

No hay manera directa. Depende de la implementación. Más arriba fallará una vez que decida introducir implementación distribuida y balanceo de carga.

+1

Mi solicitud tendrá un número limitado de usuarios en una red privada, por lo que no necesitaré la implementación distribuida. Aunque estoy de acuerdo con tu comentario. –

+0

Supongo que la forma de enmendar esto (así como también la persistencia en disco persiguiendo) sería hacer que el oyente actualice un almacén de datos compartido (Redis, Memcached o algo así) que realiza un seguimiento de las sesiones. – Thilo

Cuestiones relacionadas