¿Cómo eliminar el parámetro JSessionID en aplicaciones web?
Uno de los mayores problemas cuando estamos generando una aplicación Web es su visibilidad en los buscadores como Google, Yahoo, Bind, etc… Cada vez más estos buscadores penalizan el contenido duplicado, por lo que debemos tener mucho cuidado en que las aplicaciones Web no generen URLs distintas hacia la misma página o con el mismo contenido.
Este problema se presenta frecuentemente con las variables de sesión. Si se programa en Java, las llamadas JSessionID, que vemos en enlaces de algunas páginas. Estas variables son insertadas automáticamente cuando usamos las funciones HttpServletResponse.encodeURL o encodeRedirectURL, si el cliente no admite Cookies, como forma alternativa para mantener la sesión.
Para poder solucionar este problema de contenido duplicado podemos usar la meta canonical, de la que hablamos en su día en MasterD: http://www.masterdlabs.es/2009/la-etiqueta-meta-canonical-y-las-webs-de-master-d/.
Ahora os vamos a presentar otra forma, que elimina estas variables, las cuales son consideradas perjudiciales de cara a los buscadores. Hay que tener en cuenta que esto solo sirve si realmente no necesitamos las sesiones.
La idea principal es hacer un filtro que se anteponga en cada una de las peticiones que hacen hacia nuestras páginas y este modifique la HttpServletResponse para que cuando se hagan llamadas a encodeURL o encodeRedirectURL no inserte la variable jsessionid.
Si no estamos familiarizados con los filtros en J2EE podemos leer el siguiente articulo de la propia web de Sun: http://java.sun.com/products/servlet/Filters.html, donde se explican con gran detalle.
Un filtro es una clase Java que hereda de javax.servlet.Filter e implemente los métodos init, destroy y doFilter. Los dos primeros nos sirven si queremos hacer pre/post-procesamiento al inicio o finalización de la aplicación, por ejemplo: conseguir una conexión a la base de datos o cargar un fichero de properties.
En nuestro caso no lo utilizaremos, nos sirve simplemente con el método doFilter que es el que se ejecuta en cada petición.
Fichero UrlRewriteFilter.java:
public void doFilter(ServletRequest peticion, ServletResponse respuesta, FilterChain cadena) throws IOException, ServletException { HttpServletRequest httpPeticion = (HttpServletRequest) peticion; HttpServletResponse httpRespuesta = (HttpServletResponse) respuesta; // Envolvemos la respuesta para que no incluya el jsessionid HttpServletResponseWrapper envoltorioRespuesta = new HttpServletResponseWrapper(httpRespuesta) { @Override public String encodeRedirectUrl(String url) { return url; } @Override public String encodeRedirectURL(String url) { return url; } @Override public String encodeUrl(String url) { return url; } @Override public String encodeURL(String url) { return url; } }; chain.doFilter(peticion, envoltorioRespuesta); }
Utilizando la clase de ayuda HttpServletResponseWrapper, sobrescribimos los métodos relativos al encode, para que se ejecuten estos y no los propios de HttpServletResponse. Y simplemente devolvemos la cadena url sin modificar, así evitamos que no se inserte la variable JSessionID.
Una vez tengamos creado el filtro, debemos configurarlo. Esto lo hacemos desde el fichero web.xml.
Fichero web.xml
<filter-mapping> <filter-name>DisableUrlSessionFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter> <filter-name> DisableUrlSessionFilter </filter-name> <filter-class> es.masterd.internet.masterd.filters.DisableUrlSessionFilter </filter-class> </filter>
Una vez volvamos a desplegar nuestra aplicación, ya no tendremos más URLs con la variable JSessionID, evitando así la penalización de los buscadores por contenido duplicado.