URLs amigables con UrlRewriteFilter

0
24444

URLs amigables con UrlRewriteFilter.

0. Índice de contenidos.

1. Introducción

Son URLs amigables aquellas entendibles por el usuario, intuitivas y formadas por palabras claves relacionadas con el contenido de la página que muestran.

El objetivo es evitar la construcción de enlaces a páginas dinámicas llenos de parámetros vía GET:

http://www.miweb.com/libros/view.jsf?id=3&categoria=21

sustituyendo dicha sintaxis por otra más amigable:

http://www.miweb.com/libros/3/21/Spring-in-Action

donde Spring in Action sería el título del libro que visualizamos.

Los motivos que nos llevan a dedicar un esfuerzo adicional en este sentido son, principalmente, dos:

  • el hecho de tener URLs amigables hace que el usuario entienda la ubicación desde la propia barra de navegación, permitiendo crear bookmarks que no caduquen porque,
    por ejemplo, modifiquemos el nombre de los parámetros en un futuro,
  • no hay que olvidar que existen otros consumidores de nuestro site que no son usuarios humanos ;). Los motores de indexación de los motores de búsqueda entienden mejor las
    URLs amigables, puesto que dan un mayor peso a la página en función de los literales de la URL. Las técnicas de optimización de web sites para motores de búsqueda (SEO:
    Search Engine Optimization), entre otras muchas recomendaciones, indican que si una URL tiene más de un parámetro no será indexada; esto puede variar en función del motor
    de búsqueda, pero si tenemos en cuenta que google, hasta hace poco, no indexaba una URL que tuviese un parámetro llamado «id», vemos el esfuerzo como una necesidad.

Ya hemos hablado en adictos sobre URLs amigables con Spring MVC,
puesto que lo ideal es que el framework sobre el que desarrollamos, si implementa un patrón MVC, nos de una solución para construir este tipo de URLs.

Pero podemos no tener esa suerte, y necesitar de una implementación aparte que nos solucione nuestro problema de «URLS sucias».

La solución más limpia, si disponemos de la infraestructura necesaria, es delegar la traducción de «URL amigable» a «URL sucia» al servidor web. Apache Web Server tiene un
módulo llamado mod_rewrite que, frente a una petición, es capaz de analizar la URL y sobreescribirla, de modo que a la aplicación web le llegue otra URL totalmente diferente.
Así usamos el servidor web, como proxy que es, para realizar un mapeo entre «URL amigable» y «URL sucia», de modo que esta última sólo viva en el ámbito del servidor de aplicaciones.

Pero no siempre vamos a disponer de esta infraestructura o, disponiendo de ella, quizás no tengamos acceso a su configuración o, simplemente, no queramos depender de la gente de sistemas (sorry ;)).

Para ello, en cualquier aplicación J2EE, podemos hacer uso de un filtro en su módulo web, basado en el módulo mod_rewrite de Apache Web Server, que nos permite
sobreescribir URLs antes de llegar a nuestro código.

Examinar el filtro es el objetivo de este tutorial y su nombre es UrlRewriteFilter.

Podemos hacer uso del UrlRewriteFilter para:

  • hacer la conversión de «URL amigable» a «URL sucia» y viceversa: independientemente de la tecnología o framework con el que estemos trabajando: JSP, Servlets, Struts, JSF,…
  • detectar el navegador del cliente, de modo que permite redireccionar una petición en función del user-agent,
  • realizar una redirección programada, en función a una hora y/o fecha, ideal para realizar tareas de mantenimiento sobre el site,
  • mover contenido de forma transparente para el cliente. Lo normal es que, si realizamos una reorganización del contenido de nuestro site y este ya ha sido indexado
    por algún motor de búsqueda, perdamos el peso de las URLs tras el cambio. De este modo podemos seguir manteniendo los enlaces anteriores hasta que los nuevos cobren
    el mismo peso.

Siempre que utilizamos una nueva tecnología tratamos de buscar buenas referencias. Sobre UrlRewriteFilter:

  • le podemos encontrar en los repositorios públicos de Maven,
  • está alojado bajo code.google.com, lo cuál da garantía de mantenibilidad,
  • Jboss Seam se basa en ésta librería para realizar su conversión interna de URLs, de modo que no requiere de un fichero de configuración aparte, está integrado
    en el propio pages.xml

2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Asus G1 (Core 2 Duo a 2.1 GHz, 2048 MB RAM, 120 GB HD).
  • Sistema operativo: Windows Vista Ultimate.
  • JDK 1.5.0_15
  • Eclipse 3.4, con q4e.

3. Apache mod_rewrite.

Como hemos comentado, UrlRewriteFilter tiene la misma filosofía que el módulo de Apache Web Server mod_rewrite, de hecho es una implementación del mismo, pero como
un filtro dentro de una aplicación J2EE.

El módulo mod_rewrite es una pequeña extensión de Apache que nos permite que, frente a una petición de una URL, realmente se esté llamando a otra URL totalmente diferente.
Para ello utiliza un intérprete de expresiones regulares traduciendo URL’s en tiempo de ejecución.

Acepta las configuraciones especificadas desde el archivo global
httpd.conf, o configuraciones específicas de directorio utilizando el fichero (.htaccess).

El filtro UrlRewriteFilter se puede configurar en base a un fichero .htaccess del módulo mod_rewrite.

4. Maven: el pom.xml.

Como hemos comentado, podemos encontrar la librería en los repositorios públicos de Maven:


   ...
  
    org.tuckey
    urlrewritefilter
    3.1.0
  
   ...

También podemos descargarla e incluirla en el directorio WEB-INF/lib si no disponemos de Maven.

5. Configuración.

Debemos añadir el filtro en la configuración del descriptor de despliegue web.xml, de nuestra aplicación web:

...
    
       UrlRewriteFilter
       org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
        
        
            confReloadCheckInterval
            1
        

        
        
            confPath
            /WEB-INF/urlrewrite.xml
        

        
        
            logLevel
            DEBUG
        

        
        
            statusPath
            /rewriteStatus
        

        
        
            statusEnabled
            true
        

        
        
            statusEnabledOnHosts
            localhost
        

        
        
            modRewriteConf
            false
        
    
    
       UrlRewriteFilter
       /*
    
...

6. Parametrización.

UrlRewriteFilter usa un fichero xml, por defecto /WEB-INF/urlrewrite.xml, en el que se definen reglas.

Los parámetros en los que se definen las URLs, pueden usar el estilo de

  • expresiones regulares (por defecto). En las expresiones regulares ^ señala el inicio de una cadena y $ el final y los paréntesis permite la definición de variables accesibles vía $1, $2,…
  • expresiones con comodines.

  
  
          
  

      
    
        /some/old/*.pdf
        /very/new/$1.pdf
    
    
    
    
        ^/world/([a-z]+)/([a-z]+)$
        /world.jsp?country=$1&city=$2
    

    
    
        Mozilla/[1-4]
        ^/some/page\.html$
        /some/page-for-old-browsers.html
    

    
    
        1
        20
        22
        ^/products/$
        /products/sunday-specials.html
    

    
    
        admin
        ^/admin/(.*)$
        /go-away-please.html
    

  

La definición de la regla incluye:

  • en la etiqueta rule el atributo match-type: por defecto a regex (expresión regular) se puede configurar a wildcard,
  • from: URL de origen,
  • to: URL de destino. Permite el uso del atributo type, por defecto se realiza un forward, pero también podemos configurar un redirect, permanent-redirect,…
  • condition: para añadir condiciones a la redirección. Se pueden anidar.

Para ampliar la información sobre los parámetros de configuración recomendamos revisar la documentación sobre UrlRewriteFilter
y algunos de sus ejemplos.

7. Monitor de estado.

Si lo tenemos habilitado, y accedemos desde un host permitido, podemos visualizar el estado del filtro accediendo desde una URL parecida a esta:
http://localhost:8080/seo/rewriteStatus, donde seo es el contexto de la aplicación web y rewriteStatus
el path del monitor configurado en el web.xml.

Monitor de estado

El monitor nos informa del estado del filtro:

  • cuál es el fichero de configuración, la última vez que se leyó y cuándo se realizará la próxima lectura,
  • las reglas que tenemos activadas, y
  • la información a nivel de debug sobre la petición realizada al monitor.

8. Ejemplo.

Vamos a mostrar un ejemplo en el entorno de una aplicación con JSF.

Tenemos un listado de noticias, representado por la página /webapp/pages/news/list.jspx, que hace uso de una plantilla de facelets:




	
		Listado de noticias
		 
			

Rafa Nadal #1 ATP

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s...

Resultados de la jornada 12 de la Liga de Primera división

when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, ...

Caida y repunte de las bolsas en un lunes imprevisible

remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Otra noticia

empty.

Observamos que los enlaces al detalle de las noticias quedan fuera de componentes JSF, son simples enlaces html puesto que no queremos pasar por una regla de navegación
de JSF, sino por una regla de sobreescritura del filtro.

Configuramos el filtro, el fichero urlrewrite.xml, con la siguiente regla:


        


	
		^/news/([0-9]+)/(.*?)
		/pages/news/detail.jsf?id=$1&desc=$2
	


El enlace traducido por el filtro nos llevará a una página de detalle representada por la página /webapp/pages/news/detail.jspx, que hace uso de la misma plantilla de facelets:




	
		Listado de noticias
		
			
				

Usted está en el detalle de la noticia #, su descripción es:

La página de detalle no es más que un ejemplo que se limita a imprimir los parámetro del identificador y la descripción de la noticia. Para ello se apoya de un managed bean
que se ocupa de recuperar los valores de la request:

package com.autentia.seo;

import javax.faces.context.FacesContext;

import org.springframework.stereotype.Controller;

@Controller
public class NewsCtrl {

	public String getId(){
		return getParameter("id");
	}
	
	public String getDescription(){
		return getParameter("desc");
	}

	private String getParameter(String name){
		try {
			return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap().get(name)[0];
		}
		catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
}

El método getParameter debería ir a una clase de utilidades!.

El resultado del ejemplo queda como sigue:

Listado de noticias

Listado de noticias

Si pulsamos sobre el título de la noticia nos lleva al detalle de la misma.

Detalle de una noticia

Detalle de la noticia

Podeis comprobar cómo la barra de direcciones mantiene una URL amigable, en la que, de sólo de un vistazo, sabemos que estamos consultando una noticia sobre «tenis» y
en detalle sobre el «Número 1 de Rafa Nadal en la ATP», aunque dicha descripción a efectos de lógica de control la desechemos.

9. Conclusiones.

Si vuestro framework no os proporciona una solución para el manejo de URLs y no podéis hacer uso del módulo de Apache Web Server, mod_rewrite, con este filtro podemos
emularlo a nivel de aplicación web.

Un saludo.

Jose

mailto:jmsanchez@autentia.com

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad