Session Management (SCWCD)

Objetivos:
Section 4: Session Management
4.1- Write servlet code to store objects into a session object and retrieve objects from a session object.
4.2- Given a scenario describe the APIs used to access the session object, explain when the session object was created, and describe the mechanisms used to destroy the session object, and when it was destroyed.
4.3- Using session listeners, write code to respond to an event when an object is added to a session, and write code to respond to an event when a session object migrates from one VM to another.
4.4- Given a scenario, describe which session management mechanism the Web container could employ, how cookies might be used to manage sessions, how URL rewriting might be used to manage sessions, and write servlet code to perform URL rewriting.


Las sesiones en el protocolo HTTP
HTTP es un protocolo sin estado (stateless), cada petición al servidor web y su correspondiente respuesta es manejada como una transacción aislada. El servidor (HTTP) no tiene manera de determinar que una serie de peticiones provienen del mismo cliente.
Las sesiones, en una aplicación web, se utilizan para asociar las peticiones con el cliente. Una sesión comienza cuando un cliente desconocido envía la primera petición (que requiera crear una sesión) a la aplicación web. La misma finaliza, cuando el cliente la termina explícitamente o cuando se expira el tiempo de vida de la sesión (debido a que no se ha recibido una petición en un tiempo determinado).
La manera en que una aplicación web mantiene una sesión con el cliente es:
  • Cuando el servidor web recibe la primera petición de un cliente, el servidor inicia una sesión y le asigna un identificador único.
  • El cliente debe incluir este identificador único en cada petición subsecuente. El servidor revisa el identificador y asocia la petición con su correspondiente sesión.
Existen dos formas de implementar el soporte para sesiones, cookies y la sobreescritura de la URL.


javax.servlet.http.HttpSession
La API de servlets abstrae el concepto de sesión a través de esta interface. Cuando se inicia una sesión para un cliente, el contenedor de servlets instancia un objeto HttpSession. Los distintos servlets pueden utilizar este objeto para almacenar información relacionada al usuario y de esta manera mantener el estado del mismo. Existe un objeto HttpSession por cada sesión (o usuario). El contenedor de servlets se encarga de asociar una petición con su correspondiente objeto de sesión.
La interface javax.servlet.http.HttpServletRequest provee dos métodos para obtener la sesión:
  • HttpSession getSession (boolean create): Devuelve el correspondiente objeto sesión, o si no existe ninguna sesión y el parámetro sesión es true, crea una nueva sesión.
  • HttpSession getSession (): Método equivalente a invocar getSession (true).
Métodos de la interface HttpSession para el manejo de sus atributos:
  • void setAttribute (String name, Object value): Asocia el objeto pasado como parámetro a la sesión, y lo identifica a través del nombre.
  • Object getAttribute (String name): Devuelve el objeto asociado al nombre, o null en caso de no existir ninguno.

Manejando los eventos de sesión con las interfaces listener
En una aplicación web, cuando ocurren eventos importantes, se pueden recibir las notificaciones correspondientes a los mismos a través de las interfaces listener. Se crea una clase que implemente la interface listener correspondiente, y el contenedor de servlets invocará los métodos apropiados sobre un objeto (de esta clase) cuando ocurra algún evento.
La API de servlets define cuatro interfaces listener y dos eventos relacionados a las sesiones dentro de javax.servlet.http:
HttpSessionAttributeListener: Permite recibir notificaciones cuando se agrega, reemplaza, o elimina un atributo de un objeto HttpSession. La clase se debe especificar en el archivo web.xml. El contenedor de servlets solo crea una instancia, sobre la cual se invocaran los métodos para todas las sesiones.
  • void attributeAdded (HttpSessionBindingEvent sbe): Invocado cuando se agrega un atributo a una sesión.
  • void attributeRemoved (HttpSessionBindingEvent sbe): Invocado cuando se elimina un atributo.
  • void attributeReplaced (HttpSessionBindingEvent sbe): Invocado cuando se reemplaza un atributo.
HttpSessionBindingListener: Esta interface es implementada por aquellas clases cuyos objetos necesiten recibir notificaciones de cuando ellos son agregados y eliminados de una sesión. Esta clase no se especifica en el archivo web.xml. Cuando se agrega o elimina un objeto de una sesión, el contenedor revisa las interfaces que implementa. En caso de que el objeto implemente la interface HttpSessionBindingListener, el contenedor invoca el método correspondiente:
  • void valueBound (HttpSessionBindingEvent event): Notifica al objeto que está siendo asociado a una sesión.
  • void valueUnbound (HttpSessionBindingEvent event): Notifica al objeto que está siendo desasociado de una sesión.
HttpSessionListener: Esta interface se utiliza para recibir notificaciones de cuando una sesión se crea o se destruye. La clase que implemente dicha interface debe ser especificada en el archivo web.xml. Se crea una nueva instancia de esta clase, por cada nueva sesión creada. Posee los métodos:
  • void sessionCreated (HttpSessionEvent se): Se invoca cuando se crea una sesión.
  • void sessionDestroyed (HttpSessionEvent se): Se invoca cuando se destruye una sesión. Si dentro de este método se invoca el método getAttribute(), se lanza la excepción IllegalStateException.
HttpSessionActivationListener: (No se requiere para el examen) Esta interface se utiliza por los atributos de una sesión, para recibir notificaciones de cuando la sesión está siendo migrada a través de JVM’s en un ambiente distribuido.  De esta manera, los atributos contenidos en una sesión no se pierden, más allá de que exista más de una JVM ejecutando la aplicación. Posee los métodos:
  • void sessionDidActivate (HttpSessionEvent se): Se invoca justo después de que la sesión se activa.
  • void sessionWillPassivate (HttpSessionEvent se): Se invoca antes de desactivar la sesión.
Cerrar sesiones
La interface HttpSession provee el método:
  • void invalidate(): Cierra una sesión y desenlaza todos los objetos asociados a ella. Lanza la excepción IllegalStateException si la sesión ya ha sido cerrada.
Session timeout
El protocolo HTTP no provee ninguna señal de la terminación de una sesión en el servidor. Por este motivo, cuando el usuario no realiza ninguna acción en un período de tiempo determinado, el servidor cierra dicha sesión.
En el archivo web.xml, el elemento <session-timeout> contiene en minutos el tiempo de vida de una sesión. Un valor 0 o menor significa que la sesión nunca expirará.

    
        30
    

La interface HttpSession también posee los siguientes métodos:
  • void setMaxInactiveInterval (int seconds): Afecta solo a la sesión en la cual se invoca. Las demás, mantienen el tiempo especificado en el archivo web.xml.
  • void getMaxInactiveInterval ()
Existen dos inconsistencias entre estos modos de setear el timeout:
  1. El valor de elemento <session-timeout> se especifica en minutos, mientras que setMaxInactiveInterval() en segundos.
  2. El valor 0 o menos en el elemento <session-timeout> significa que la sesión nunca expirará, mientas que al método setMaxInactiveInterval() se le debe pasar un valor negativo (no 0) para conseguir el mismo comportamiento.

Utilización de cookies
En esta técnica, para enviar y recibir el identificador de una sesión, el contenedor de servlets utiliza los encabezados (headers) HTTP. Cuando se devuelve la respuesta, el contenedor agrega un encabezado especial que contiene el identificador de sesión. El cliente, el cual es típicamente un browser, extrae este encabezado especial, y lo almacena en la máquina local. Cuando se realiza otra petición, el cliente agrega automáticamente un encabezado que contiene el identificador de sesión almacenado. Este archivo almacenado se denomina cookie.
Cuando las cookies se encuentran deshabilitadas, el browser ignora cualquier encabezado que contenga cookies, y consecuentemente no envía ningún encabezado con cookies en la petición.


Sobreescritura de URL’s
Esta alternativa permite añadir, dentro de una respuesta, el identificador de sesión en todas las URL’s. De esta manera, cuando el usuario interactúe con el sitio, enviará automáticamente su identificador de sesión como parte de la petición.
Este mecanismo no es tranparente al desarrollador (a diferencia de las cookies). La interface HttpServletResponse provee los métodos:
  • String encodeURL (String url): Devuelve la url con el identificador de sesión adjuntado.
  • String encodeRedirectURL (String url): Idem anterior, pero se utiliza junto con el método sendRedirect().
Ambos métodos verifican si es necesario adjuntar el identificador. Si la petición contiene un encabezado de cookie, entonces las mismas están habilitadas en el browser cliente, y la sobreescritura de la url no es necesaria.
Se debe tener en cuenta que en la URL, el ID de la sesión se agrega luego del carácter ‘;’. Por ejemplo:
http://localhost:8080/scwcd/LoginServlet;jsessionid=1C9B3BAE94BE88AD45AA54B2A8AC0246?user=matias
Esto se debe a que jsessionid es parte del path info de la petición, y no es un parámetro de la misma. Este valor NO puede ser accedido a través del método HttpServletRequest.getParameter(“jsessionid”).


0 comentarios :: Session Management (SCWCD)

Publicar un comentario en la entrada