sesion pestaña page navegador mensaje event detectar cuando close cierra cerrar cambio boton before java session

java - pestaña - jquery on exit page



Java: ¿Por qué la sesión http no se destruye cuando se cierra la pestaña o el navegador? (8)

Tengo la siguiente implementación de HttpSessionlistener

public class SessionListener implements HttpSessionAttributeListener, HttpSessionListener { public void attributeAdded(HttpSessionBindingEvent event) { ... } public void attributeRemoved(HttpSessionBindingEvent event) { ... } public void attributeReplaced(HttpSessionBindingEvent event) { } //HttpSesion creation & destruction public void sessionCreated(HttpSessionEvent event) { HttpSession session = event.getSession(); //log created time } public void sessionDestroyed(HttpSessionEvent event) { HttpSession session = event.getSession(); long destroyedTime = System.currentTimeMillis(); //log destroyed time }

}

Básicamente, registro la hora de creación y destrucción de la sesión. Pero si la sesión es larga (predeterminada a 30 minutos), y el usuario cierra el navegador mientras tanto,

sessionDestroyed

no se llama?

Porqué es eso ? ¿Existe alguna solución alternativa para registrar exactamente cuándo se destruyó la sesión (cuando el usuario cierra el navegador)? ¿No debería ser este el problema del navegador para cerrar la sesión cuando está cerrada?

¿Hay alguna interfaz que tenga que implementar para que esto funcione?

Gracias !


¿Cómo sabría el servidor cuando se cierra el navegador o se cierra la pestaña? En ese momento el navegador no envía nada al servidor.

Esta es una parte fundamental de HTTP: es un protocolo de solicitud / respuesta, no una "conversación abierta de forma permanente" en la que se puede saber si una de las partes abandona la conversación. Piense en ello como una serie de telegramas en lugar de una llamada telefónica, y no puede saber cuándo recibió el último telegrama que recibirá.

Deberá diseñar su camino alrededor de esto, para evitar saber cuándo se ha cerrado el navegador. Hay algunos trucos feos para solucionarlo, por ejemplo, hacer que AJAX examine el servidor con un mensaje de latido, pero cambiar el diseño es una solución mejor.


Como Eric mencionó, el evento de descarga en el navegador puede llamar a una función javascript, que a su vez puede acceder a una url a través de un servlet que cierra la sesión. No es necesario esperar la respuesta real del servlet.

El navegador web interactúa con el servidor a través del protocolo http y no tiene estado.


Los objetos de sesión viven en el servidor y son controlados por el servidor. Solo el servidor puede crear o destruir sesiones. Entonces, si el cliente está cerrado, la sesión continúa hasta que caduque. El cliente solo puede sugerir al servidor que puede destruir alguna sesión. Esta solicitud debe ser explícita de alguna manera. Por lo tanto, cuando cierra una ventana del navegador, no hay una solicitud implícita al servidor que le informe que debe destruir una sesión determinada.


Si necesita que la sesión se destruya cuando se cierra una ventana / pestaña del navegador, puede adjuntar un controlador de JavaScript al evento onunload que realiza algún tipo de llamada AJAX a un recurso que llama a la sesión.

Tenga en cuenta que el evento onunload no siempre se activa, por lo que no es totalmente confiable. Una forma confiable podría ser usar un sistema de "latido".


Sin mucho trabajo, el navegador no informa al servidor que la ventana está cerrada, por lo que Java no puede saber cuándo destruir la sesión. Por lo tanto, el tiempo de espera está en su lugar y es el primero que el servidor sabe que esta sesión se puede destruir.

Puede probar y reproducir una llamada ajax en el evento de javascript document.onunload https://developer.mozilla.org/en/DOM/window.onunload pero deberá asegurarse de que el usuario aún no esté dentro de su sitio cuando hacer esto.


hay algunos hacks para saber el siguiente código para destruir la sesión cuando el usuario cierra el navegador

lado del cliente:

<script src="jquery path"></script> <script> window.onunload = function(){ $.get("${request.contextPath}/logout"); } </script>

lado del servidor: crear una asignación de solicitud para "/ logout"

public void doGet(HttpServletRequest request, HttpServletResponse) { request.getSession().invalidate(); System.out.println(''destroy from logout on unload browser''); }

El siguiente código es opcional

utilizar el escucha de sesión cuando quiera saber cuándo se destruyó la sesión

// in class import javax.servlet.*; import javax.servlet.http.*; public class SesListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent se) { System.out.println("Session created..."); } public void sessionDestroyed(HttpSessionEvent se) { System.out.println("Session destroyed..."); } } //----------------------------------------- // in web.xml <listener> <listener-class>SesListener</listener-class> </listener>


solo puedes verificar si tu usuario de sesión, no es nulo como:

if (session.getAttribute("user") != null ) sessionsetAttribute("user","null");


NOTA: Como jwenting continuación, esto no es 100% seguro en absoluto. Si el evento de descarga no se desencadena por un evento de cierre de la pestaña o ventana del navegador, esto fallará.

Tuve el mismo problema y resuélvalo utilizando un evento de JavaScript intrusivo:

window.onunload

Déjame explicarte brevemente, digamos que tienes una función de JavaScript que publica, usando jQuery, el ID de sesión actual para ese Servlet para invalidarla, como esto:

function safeexit(){ $.post("/SessionKillServlet", { SID = <%=session.getId()%> }, function(data){}); }

Para llamar a esa función, solo necesitas unirla así:

window.onunload = safeexit; //without the ()

Ahora, se llamará al método safeexit cuando se cierre la ventana TAB o BROWSER (o en una redirección).