Ejemplo de Filtros
Dentro de la especificación de Java Servlets, existe un componente llamado filtros. Estos nos ayudan a analizar o transformar las peticiones hechas a las páginas Web, ya sean jsps o servlets. Estos filtros trabajan de forma encadenada, por lo que se puede crear una serie de filtros que van pasando el control de uno al otro.
Los Filtros son muy sencillos de implementar, y son componentes altamente reutilizables que nos dan mucho poder sobre las aplicaciones web. Nos permite por ejemplo, controlar el acceso a la aplicación, manejo de compresión de datos, transformaciones, auditoria, registro, cifrado, manejo de sesiones, en fin, un sinnúmero de utilidades que se adaptan a nuestras necesidades.
En este ejemplo veremos como implementar un filtro que nos ayudara con una sencilla tarea: detectar el timeout de nuestra sesión. Cuando un usuario deja morir su sesión, no teniendo actividad en 30 minutos por ejemplo, esta se destruye, causando que si el usuario solicita una página que maneje datos de la sesión, esta regresara errores y resultados no esperados.
Empecemos creando nuestro filtro. Lo llamaremos SessionFilter.
Tenemos que crear una clase que implemente la interfaz javax.servlet.Filter. Esta interfaz contiene 3 métodos:
doFilter: Este es el mas importante ya que es el que realiza toda la actividad del filtro. Además de disparar el resto de los filtros.
Init: Este método es llamado cuando el filtro es inicializado en el contenedor.
Destroy: Este método es llamado cuando el filtro es destruido por el contenedor.
Nuestro filtro vacio quedaria como sigue, nota el chain.doFilter, este ejecuta el resto de los filtros pendientes:
package net.novacreations.example.filter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SessionFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
try {
//Podemos seguir ejecutando los demas filtros si asi lo necesitamos
chain.doFilter(request, response);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
}
Una vez creado nuestro filtro, tenemos que definirlo en el web.xml, así que vamos a este archivo. Además de la definición de nuestros servlets y otros atributos, debemos de indicarle los filtros, y sus mapeos:
Para nuestro ejemplo, quedaría así:
Ya con esto, nuestro filtro será inicializado la próxima vez que hagamos un deploy. Este se ejecutara cada vez que una solicitud concuerde con la url-pattern, en este caso siempre que se ejecute el servlet sessionTest. Pero también podríamos pedirle que se ejecute con todos los jsps, htmls o todos los servlets, con el patrón que necesitemos.
Ahora ya estamos listos para meterle código a nuestro filtro. En este caso nuestro servlet sessionTest asume que la sesión existe, por lo que tenemos que verificar en cada solicitud si esto es cierto y en caso contrario mandarlo a una pagina con un aviso de timeout.
Podemos mandar a pedir la sesión, y si esta no existe, podemos considerar que ha sido eliminada.
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpSession session= httpRequest.getSession(false);
Al mandarle false como parámetro, evitamos que cree una nueva sesión en blanco. Así que si sesión es null, nuestra sesión ha expirado.
Tenemos que considerar que si tenemos jsps, la lógica puede cambiar. Los jsps al ser cargados crean por defecto una sesión si es que esta no existe. Por lo que si nuestra aplicación carga jsps antes de llegar a nuestro servlet, va a crear una nueva sesión sin relación con la sesión expirada, por lo que los datos que necesitamos ya se perdieron. Para esto podemos preguntar además por una variable que nos sirve de bandera, por ejemplo el nombre de usuario o algún otro dato que nuestra aplicación siempre maneje. En este caso, si ese dato no existe, podemos considerar la sesión como perdida.
Object usuario = session.getAttribute(“nombre”);
Aquí si el usuario es nulo, nuestra sesión esta perdia.
Por lo que nuestro doFilter quedaría así:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
System.out.println("FILTER");
//Cargamos la sesion
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpSession session= httpRequest.getSession(false);
Object usuario = null;
//Preguntamos por un objeto en la sesion
if(session!=null)usuario=session.getAttribute("nombre");
if(session==null || usuario==null)System.out.println("Session Invalid");
else System.out.println("Session valid");
if (session==null || usuario==null) {//if we have no session
try {
httpRequest.getRequestDispatcher("/timeout.html").forward(request, response);
return;
}
catch (ServletException e) { }
catch (IOException e) {}
}
try {
chain.doFilter(request, response);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
Con el método httpRequest.getRequestDispatcher lo que hacemos es mandar como respuesta una url diferente, en este ejemplo en mensaje de timeout.
Una vez cargado este filtro dentro de nuestra aplicación, este mostrara el mensaje de Timeout cada vez que el usuario deje morir su sesión al no tener actividad sobre la misma. Puedes ver un ejemplo listo para el deploy en
http://www.novacreations.net/192-ejemplo-de-filtros-en-aplicacion-web-java-servlets/ Cuenta con todas los códigos fuentes.
Acomodar codigo