2. Manejo de Cookies y de Sesiones

 

Veremos en este tema aspectos sobre el seguimiento de las acciones de los usuarios sobre un sitio web. Para ello veremos cómo trabajar con cookies en los servlets, y cómo manejar información sobre las sesiones de los usuarios.

 

2.1. Cookies

Una cookie es un objeto de tipo:

nombre = valor

donde se asigna un valor determinado (una cadena de texto) a una variable del nombre indicado. Dicho objeto es almacenado y recordado por el servidor web y el navegador durante un período de tiempo (indicado como un parámetro interno de la propia cookie). Así, se puede tener una lista de cookies con distintas variables y distintos valores, para almacenar información relevante para cada usuario (se tienen listas de cookies independientes para cada usuario).

En Javascript, por ejemplo, el objeto document.cookie contiene como valor una lista de la forma:

nombre1=valor1;nombre2=valor2;...;nombreN=valorN

donde se almacenan así los valores de las cookies que se tengan definidas.

Se pueden emplear cookies, entre otras cosas, para:

Los navegadores que trabajen con cookies pueden soportar hasta 20 cookies por servidor, de al menos 4 KB cada una. Los servlets que se ejecutan en un mismo servidor comparten las cookies.

A la hora de trabajar con cookies, debemos tener en cuenta que nuestro sitio web no debe depender de ellas, puesto que muchos navegadores y usuarios las deshabilitan para evitar problemas de privacidad y otras cuestiones.

Veremos ahora cómo trabajar con cookies desde servlets.

2.1.1. Enviar una cookie

Para crear una nueva cookie y enviarla, se siguen los pasos:

1. Crear la cookie

Las cookies se manejan con la clase Cookie. Se tiene el constructor:

public Cookie (String nombre, String valor)

que crea una cookie de nombre nombre, dándole el valor valor.

2. Establecer los atributos de la cookie

Una vez creada la cookie, podemos establecer los atributos que queramos, con los métodos de la clase Cookie. Por ejemplo, se tienen:

public void setComment(String comentario)
public void setMaxAge(int edad)
...

El primero asigna una cadena descriptiva sobre la cookie. El segundo indica cuántos segundos de vida tiene. Si es un valor negativo, se borrará la cookie cuando se cierre el navegador. Si el valor es 0, se borra la cookie instantáneamente, y si es positivo, se borrará la cookie cuando pasen los segundos indicados (si cerramos y volvemos a abrir el navegador dentro de ese tiempo, la cookie todavía persistirá). Se tienen otros métodos para establecer atributos de la cookie.

3. Enviar la cookie

Las cookies se añaden a la cabecera de la respuesta, y se envían así al cliente, mediante el método de HttpServletResponse:

public void addCookie (Cookie cookie)

Ejemplo

Vemos un ejemplo completo de envío de cookie:

public class MiServlet extends HttpServlet 
{ 
	public void doGet (HttpServletRequest request, 
			   HttpServletResponse response) 
	throws ServletException, IOException
	{	
		Cookie miCookie = new Cookie ("nombre", "Pepe");
		miCookie.setMaxAge(120);
		response.addCookie(miCookie);
		PrintWriter out = response.getWriter();
		...
	}
}

Hay que tener en cuenta que las cookies son parte de la cabecera HTTP, con lo cual hay que enviarlas ANTES de escribir la respuesta (o antes de obtener el objeto Writer si lo queremos utilizar).

2.1.2. Obtener una cookie

Para obtener una cookie que envía el cliente se trabaja sobre la petición del cliente (HttpServletRequest), siguiendo los pasos:

1. Obtener todas las cookies

Obtenemos todas las cookies con el método getCookies() de la clase HttpServletRequest:

public Cookie[] getCookies()

Con esto se tiene un array con todas las cookies actuales para el usuario. Si no hay cookies el método devuelve null.

2. Obtener el valor de una cookie

Con lo anterior, para obtener el valor de una cookie simplemente recorremos el array de cookies buscando la que concuerde con el nombre que queramos. Pueden ser útiles los métodos de Cookie:

public String getName()
public String getValue()

El primero obtiene el nombre de la cookie, y el segundo el valor.

Ejemplo

Un ejemplo de uso, para obtener el nombre del usuario, guardado en la cookie "nombre":

public void doGet (HttpServletRequest request, 
		   HttpServletResponse response) 
throws ServletException, IOException
{	
	Cookie[] cookies = request.getCookies();
	String nombre;
	for (int i = 0; i < cookies.length; i++)
		if (cookies[i].getName().equals("nombre"))
			nombre = cookies[i].getValue();
}

2.1.3. Ejemplo

Aquí tenéis un WAR con un ejemplo de uso de cookies. El servlet ServletCookies cuenta el número de visitas a una página con una cookie que dura 3 minutos.

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ServletCookies extends HttpServlet
{
   // Metodo para GET
	
   public void doGet(HttpServletRequest request, 
		     HttpServletResponse response) 
   throws ServletException, IOException
   {
	response.setContentType("text/html");
	response.setHeader("Cache-Control", "no-cache");
		
	Cookie[] cookies = request.getCookies();
	Cookie contador = buscaCookie("contador", cookies);
		
	if (contador == null)
	{
	   // Creamos la cookie con el contador
			
	   Cookie cookie = new Cookie ("contador", "1");
	   cookie.setMaxAge(180);
	   response.addCookie(cookie);

	   // Mostramos el mensaje de primera visita

	   PrintWriter out = response.getWriter();
	   out.println ("<HTML>");			
	   out.println ("<BODY>");			
	   out.println ("Primera visita"); 
	   out.println ("<BR>");
	   out.println ("</BODY>");
	   out.println ("</HTML>");

	} else {
		
	   // Obtenemos el valor actual del contador
			
	   int cont = Integer.parseInt(contador.getValue());
	   cont++;
			
	   // Modificamos el valor de la cookie 
	   // incrementando el contador
			
	   Cookie cookie = new Cookie ("contador", "" + cont);
	   cookie.setMaxAge(180);
	   response.addCookie(cookie);

	   // Mostramos el numero de visitas

	   PrintWriter out = response.getWriter();
	   out.println ("<HTML>");
	   out.println ("<BODY>");
	   out.println ("Visita numero " + cont);
	   out.println ("<BR>");
	   out.println ("</BODY>");
	   out.println ("</HTML>");
	}		
   }	
	
   // Busca la cookie 'nombre' 
   // en el array de cookies indicado. 
   // Devuelve null si no esta
	
   private Cookie buscaCookie(String nombre, 
			      Cookie[] cookies)
   {
	if (cookies == null)
	   return null;
		
	for (int i = 0; i < cookies.length; i++)
	   if (cookies[i].getName().equals(nombre))
		return cookies[i];
		
	return null;
   }
}

Copiad el ejemplo en el directorio webapps de Tomcat, reiniciar el servidor y probadlo con:

http://localhost:8080/ejemplocookies/servlet/ServletCookies