Servlets (Básico)

El seguimiento de sesi�n es un mecanismo que los servlets utilizan para mantener el estado sobre la serie de peticiones desde un mismo usuario (esto es, peticiones originadas desde el mismo navegador) durante un periodo de tiempo.

Las sesiones son compartidas por los servlets a los que accede el cliente. Esto es conveniente para aplicaciones compuestas por varios servlets. Por ejemplo, Duke's Bookstore utiliza seguimiento de sesi�n para seguir la pista de los libros pedidos por el usuario. Todos los servlets del ejemplo tienen acceso a la sesi�n del usuario.

Para utilizar el seguimiento de sesi�n debemos.

  • Obtener una sesi�n (un objeto HttpSession) para un usuario.
  • Almacenar u obtener datos desde el objeto HttpSession.
  • Invalidar la sesi�n (opcional).

.�Obtener una Sesi�n

El m�todo getSession del objeto HttpServletRequest devuelve una sesi�n de usuario. Cuando llamamos al m�todo con su argumento create como true, la implementaci�n crear� una sesi�n si es necesario.

Para mantener la sesi�n apropiadamente, debemos lamar a getSession antes de escribir cualquier respuesta. (Si respondemos utilizando un Writer, entonces debemos llamar a getSession antes de acceder al Writer, no s�lo antes de enviar cualquier respuesta).

El ejemplo Duke's Bookstore utiliza seguimiento de sesi�n para seguir la pista de los libros que hay en la hoja de pedido del usuario. Aqu� tenemos un ejemplo de CatalogServlet obteniendo una sesi�n de usuario.

    public class CatalogServlet extends HttpServlet { 

        public void doGet (HttpServletRequest request,
                           HttpServletResponse response)
    	throws ServletException, IOException
        {
            // Get the user's session and shopping cart
	    HttpSession session = request.getSession(true);
            ...
	    out = response.getWriter();
            ...
        }
    }

.�Almacenar y Obtener Datos desde la Sesi�n

El Interface HttpSession proporciona m�todos que almacenan y recuperan.

  • Propiedades de Sesi�n Est�ndard, como un identificador de sesi�n.
  • Datos de la aplicaci�n, que son almacenados como parejas nombre-valor, donde el nombre es un string y los valores son objetos del lenguaje de programaci�n Java. Como varios servlets pueden acceder a la sesi�n de usuario, deberemos adoptar una convenci�n de nombrado para organizar los nombres con los datos de la aplicaci�n. Esto evitar� que los servlets sobreescriban accidentalmente otros valores de la sesi�n. Una de esas convenciones es servletname.name donde servletname es el nombre completo del servlet, incluyendo sus paquetes. Por ejemplo, com.acme.WidgetServlet.state es un cookie con el servletname com.acme.WidgetServlet y el name state.

El ejemplo Duke's Bookstore utiliza seguimiento de sesi�n para seguir la pista de los libros de la hoja de pedido del usuario. Aqu� hay un ejemplo de CatalogServlet obteniendo un identificador de sesi�n de usuario, y obteniendo y seleccionando datos de la aplicaci�n asociada con la sesi�n de usuario.

    public class CatalogServlet extends HttpServlet { 

        public void doGet (HttpServletRequest request,
                           HttpServletResponse response)
    	throws ServletException, IOException
        {
            // Get the user's session and shopping cart
	    HttpSession session = request.getSession(true);
	    ShoppingCart cart =
                (ShoppingCart)session.getValue(session.getId());

        // If the user has no cart, create a new one
        if (cart == null) {
            cart = new ShoppingCart();
            session.putValue(session.getId(), cart);
        }
            ...
        }
    }

Como un objeto puede ser asociado con una sesi�n, el ejemplo Duke's Bookstore sigue la pista de los libros que el usuario ha pedido dentro de un objeto. El tipo del objeto es ShoppingCart y cada libro que el usuario a seleccionado es almacenado en la hoja de pedidos como un objeto ShoppingCartItem. Por ejemplo, el siguiente c�digo procede del m�todo doGet de CatalogServlet.

    public void doGet (HttpServletRequest request,
                       HttpServletResponse response)
	throws ServletException, IOException
    {
	HttpSession session = request.getSession(true);
	ShoppingCart cart = (ShoppingCart)session.getValue(session.getId());
        ...
        // Check for pending adds to the shopping cart
        String bookId = request.getParameter("Buy");

        //If the user wants to add a book, add it and print the result
        String bookToAdd = request.getParameter("Buy");
        if (bookToAdd != null) {
            BookDetails book = database.getBookDetails(bookToAdd);

            cart.add(bookToAdd, book);
            out.println("<p><h3>" + ...);
        }
    }

Finalmente, observa que una sesi�n puede ser designada como nueva. Una sesi�n nueva hace que el m�todo isNew de la clase HttpSession devuelva true, indicando que, por ejemplo, el cliente, todav�a no sabe nada de la sesi�n. Una nueva sesi�n no tiene datos asociados.

Podemos tratar con situaciones que involucran nuevas sesisones. En el ejemplo Duke's Bookstore, si el usuario no tiene hoja de pedido (el �nico dato asociado con una sesi�n), el servlet crea una nueva. Alternativamente, si necesitamos informaci�n sobre el usuario al iniciar una sesi�n (como el nombre de usuario), podr�amos querer redireccionar al usuario a un "p�gina de entrada" donde recolectamos la informaci�n necesaria.

.�Invalidar la Sesi�n

Una sesi�n de usuario puede ser invalidada manual o autom�ticamente, dependiendo de donde se est� ejecutando el servlet. (Por ejemplo, el Java Web Server, invalida una sesi�n cuando no hay peticiones de p�gina por un periodo de tiempo, unos 30 minutos por defecto). Invalidar una sesi�n significa eliminar el objeto HttpSession y todos sus valores del sistema.

Para invalidar manualmente una sesi�n, se utiliza el m�todo invalidate de "session". Algunas aplicaciones tienen un punto natural en el que invalidar la sesi�n. El ejemplo Duke's Bookstore invalida una sesi�n de usuario despu�s de que el usuario haya comprado los libros. Esto sucede en el ReceiptServlet.

    public class ReceiptServlet extends HttpServlet { 

        public void doPost(HttpServletRequest request,
                           HttpServletResponse response)
	    throws ServletException, IOException {

                ...
                scart = (ShoppingCart)session.getValue(session.getId());
                ...
                // Clear out shopping cart by invalidating the session
                session.invalidate();

                // set content type header before accessing the Writer
                response.setContentType("text/html");
                out = response.getWriter();
                ...
        }
    }

.�Manejar todos los Navegadores

Por defecto, el seguimiento de sesi�n utiliza cookies para asociar un identificador de sesi�n con un usuario. Para soportar tambi�n a los usuarios que acceden al servlet con un navegador que no soporta cookies, o si este est� programado para no aceptarlas. debemos utilizar reescritura de URL en su lugar.

Cuando se utiliza la reescritura de URL se llama a los m�todos que, cuando es necesario, incluyen el ID de sesi�n en un enlace. Debemos llamar a esos m�todos por cada enlace en la respuesta del servlet.

El m�todo que asocia un ID de sesi�n con una URL es HttpServletResponse.encodeUrl. Si redirecionamos al usuario a otra p�gina, el m�todo para asociar el ID de sesi�n con la URL redirecionada se llama HttpServletResponse.encodeRedirectUrl.

Los m�todos encodeUrl y encodeRedirectUrl deciden si las URL necesitan ser reescritas, y devolver la URL cambiada o sin cambiar. (Las reglas para las URLs y las URLs redireccionadas son diferentes, pero en general si el servidor detecta que el navegador soporta cookies, entonces la URL no se reescribir�).

El ejemplo Duke's Bookstore utiliza reescritura de URL para todos los enlaces que devuelve a sus usuarios. Por ejemplo, el CatalogServlet devuelve un catalogo con dos enlaces para cada libro. Un enlace ofrece detalles sobre el libro y el otro ofrece al usuario a�adir el libro a su hoja de pedidos. Ambas URLs son reescritas.

    public class CatalogServlet extends HttpServlet { 

        public void doGet (HttpServletRequest request,
                           HttpServletResponse response)
	    throws ServletException, IOException
        {
            // Get the user's session and shopping cart, the Writer, etc.
            ...
	    // then write the data of the response
            out.println("<html>" + ...);
            ...
            // Get the catalog and send it, nicely formatted
            BookDetails[] books = database.getBooksSortedByTitle();
            ...
            for(int i=0; i < numBooks; i++) {
                ...
                //Print out info on each book in its own two rows
                out.println("<tr>" + ...
                        "<a href=\"" +
                        response.encodeUrl("/servlet/bookdetails?bookId=" +
                                           bookId) +
                        "\"> <strong>" + books[i].getTitle() +
                        "� </strong></a></td>" + ...
                        "<a href=\"" +
                        response.encodeUrl("/servlet/catalog?Buy=" + bookId)
                        + "\"> � Add to Cart �</a></td></tr>" +

            }
        }
    }

Si el usuario pulsa sobre un enlace con una URL re-escrita, el servlet reconoce y extrae el ID de sesi�n. Luego el m�todo getSessionutiliza el ID de sesi�n para obtener el objeto HttpSession del usuario.

Por otro lado, si el navegador del usuario no soporta cookies y el usuario pulsa sobre una URL no re-escrita. Se pierde la sesi�n de usuario. El servlet contactado a trav�s de ese enlace crea una nueva sesi�n, pero la nueva sesi�n no tiene datos asociados con la sesi�n anterior. Una vez que un servlet pierde los datos de una sesi�n, los datos se pierden para todos los servlets que comparten la sesi�n. Debemos utilizar la re-escritura de URLs consistentemente para que nuestro servlet soporte clientes que no soportan o aceptan cookies.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP