URLs amigables con UrlRewriteFilter

UrlRewriteFilter es un filtro que se basa en el mod_rewrite de Apache HTTP Server, para permitir el uso de urls amigables en aplicaciones J2EE y que hacía bastante tiempo que tenía pendiente de probar.

La forma de usar este filtro es realmente sencilla, simplemente debemos añadir el filtro a nuestro web.xml:

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>INFO</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Y debemos tener en el directorio WEB-INF el archivo urlrewrite.xml, donde configuraremos nuestras urls amigables. Por ejemplo si quisieramos cambiar unas urls de struts como miaction.do?identificador=1 para que fueran más amigables para los buscadores por ejemplo de esta forma miaction/1.

<rule>
  <from>^/miaction/([0-9]+)$</from>
  <to type="forward">/miaction.do?identificador=$1</to>
</rule>

Hay varios ejemplos de uso en la web del proyecto si quieres ver otras situaciones más concretas dónde utilizar este filtro.

Libro: The Pragmatic Programmer

He acabado, al fin, de leer el libro The Pragmatic Programmer. Es un libro que debería leer cualquiera que trabaje como programador, ya que se dan una serie de consejos para mejorar en nuestro trabajo y no se centra en un lenguaje en concreto, aunque se ponen algunos pequeños ejemplos de código en Java, C y Perl.

Es un libro de buenas prácticas generales de programación, esto lleva a que algunos temas se toquen de manera algo superficial, aunque si profundizara el libro sería muchísimo más extenso. Para mi el libro ha resultado inspirador, sobre todo porque gran parte son buenas prácticas en cuanto a la actitud de un programador (no des excusas provee opciones, no te repitas, prueba tu software, piensa críticamente sobre tu trabajo...).

Otras ideas que resultan interesantes son la automatización de procesos (realización de pruebas, generación de código, generación de documentación...) o la organización de código (separa vista y modelo, diseña usando servicios, refactoriza pronto y a menudo, diseña para probar, diseña con contratos...).

En conclusión, es un libro muy recomendable, donde se encuentran algunas ideas que ya conoceremos, pero que en muchas ocasiones no aplicamos, y que resulta fácil de leer gracias al uso de metáforas o de ejemplos

Integrar Spring y Struts

Hace ya algún tiempo que ando tocando algunas cosas de Spring framework. Un framework que simplifica el desarrollo de aplicaciones J2EE, que entre otras cosas nos permite desacoplar partes de nuestro código gracias a Spring IoC.

A raíz de un post en programania, en donde explican dos formas de integrar spring con struts, voy a aprovechar para explicar aquí las otras dos alternativas para hacerlo.

  • Nuestros Actions deben extender de ActionSupport: de esta forma se facilita la obtención del contexto de spring manualmente, que es la forma más sencilla de hacerlo. El problema, evidentemente que de esta forma las Actions de struts quedan muy aclopadas a spring.
  • Usando DelegatingRequestProcessor (o en el caso de usar Tiles DelegatingTilesRequestProcessor): le pasamos el manejo de las acciones a spring sobre-escribiendo el RequestProcessor de struts. De esta forma desacomplamos los Actions de spring, aunque nos puede surgir el problema que vayamos a usar un RequestProcessor propio, por lo que deberíamos usar el DelegatingActionProxy, que es la forma que explican en programania.

La pega que surge al delegar el manejo de los Actions a Spring con DelegatingRequestProcessor y DelegatingActionProxy, es que hay que definir en el beans.xml nuestros actions de struts. En el primer caso, en el struts-config definiremos (como siempre) nuestros actions, por lo que deberemos mantener las mismas actions en dos XML diferentes, sólo cambia que definimos:

controller processorClass = "org.springframework.web.struts.DelegatingRequestProcessor"

mientras que en el segundo, para cada action de struts-config le pondremos el type DelegatingActionProxy:

type = "org.springframework.web.struts.DelegatingActionProxy"

En conclusión, es recomendable delegar el manejo de las acciones a spring aunque tengamos que mantener dos XML diferentes, ya que la integración es más transparente y además tendremos la opción de utilizar Spring AOP. Mientras que extender de ActionSupport resultaría útil para utilizar varios contextos de spring distintos.

Para encontrar una explicación mucho más detallada y con ejemplos, en developerWorks hay un artículo disponible.

Conociendo el Eye Tracking

Este viernes, estuve en el taller de eyetracking en el laboratorio aragonés de usabilidad en walqa al que asistimos entre unas 25-30 personas. Personalmente, me llamó la atención que viniera gente desde Pamplona, Logroño y Tortosa, aparte de los que veníamos de Zaragoza claro; se puedo comprobar la expectación que ha levantó el "cacharro" en cuestión.

Después del acto de bienvenida, empezamos con una presentación técnica del Eye Tracker de Tobii y de su software, por parte de Elena Lafuente. Nos explicó que se puede utilizar para pruebas en muchos contextos (sitios web, secuencias de imágenes, videos, escaparates...), que se toman una gran cantidad de datos del movimiento de los ojos, la visualización gráfica de los datos (individuales o de conjuntos) y de la posibilidad de exportar los datos recogidos. Tiene múltiples aplicaciones, como pueden ser desde la usabilidad de una web, a publicidad (web, en papel...) o incluso para estudios psicológicos.

Siguió Daniel Torres con una presentación de conclusiones de estudios de eye tracking, para ver algunas "reglas" de usabilidad web que se han sacado gracias a los eye trackers.

Finalmente se realizó una sesión práctica, en la que se utilizó una secuencia de imágenes, se "compró" un portátil en la web de apple y unos zapatos rojos en otra web, de esta forma, nos hicimos una idea de su funcionamiento en directo.

Esperemos a ver si tienen tiempo y pueden desarrollar alguna aplicación interesante con el SDK de Tobii para el tracker, que por defecto profesional me llamó bastante la atención tener la opción de hacerlo.

En el blog del laboratorio, han publicado algunas fotos y videos de las sesiones prácticas.

Actualización, otros sitios donde hablan del taller:
Mamen Pradel
Dani Torres, que ha subido a slideshare su presentación y algunas fotos a picasa
The Stromboli Project
Miguel Galve
Ricardo Gil

Y creo que no me dejo a nadie :)

Command Objects para validaciones de formularios

Llevo unos días jugando un poco con Grails y es un framework que estoy viendo bastante interesante, como también ir aprendiendo groovy.

La cuestión es que después de ir probando diferentes cosas del framework, y ver la facilidad que dan los constraints para las validaciones en las clases del dominio, pensé la situación de registro de un usuario. En esta situación, se suele utilizar un segundo campo para confirmar la contraseña, por lo que no podía validar esta situación en los constraints de la clase de dominio del usuario ya que password2 no forma parte de él.

La solución es utilizar los Command Objects, que tal y como dice la documentación sería algo como los form bean en struts. Estas clases se suelen declarar en el mismo fichero que el Controller que lo va a utilizar, y se definen los constraints de la misma forma que en las clases del dominio.

En mi caso, necesitaba comparar dos parámetros del formulario, para esto debía usar un constraint propio:

password1( validator: {
val, obj ->
obj.password2 == val
})

La validación se hace sobre password1, val es password1, obj -> es MiCommandObject y con obj.password2==val vemos si son iguales. Esto es porque si el clousure recibe dos parámetros, el primero toma el valor y el segundo el objeto de referencia(en este caso el Command Object).

Mi conclusión en cuanto a la documentación oficial de Grails, es que ya hay bastante cantidad de información pero en algunos momentos demasiado dispersa.