martes, mayo 06, 2008

Repasando los cambios en Servlets 3.0

martes, mayo 06, 2008 por Martín

Recuerdo hace años que me solía leer muchas de las especificaciones del JCP conforme iban apareciendo. Vaya, esto me hace sentirme como un verdadero bicho raro. Pero es que me resultaba bastante interesante ver como evolucionaba la especificación de EJBs, leer sobre JDO, aprender sobre JCR e intentar hacer una implementación o pegar un giro radical y leer sobre J2ME o CLDC. Con el paso de los años me he ido desenganchando :-) No sé si es la edad, o si más bien es que hay tantas especificaciones ahora mismo que te da pereza siquiera echarles un vistazo.

Aún así, hoy he vuelto a esa vieja adicción y me he leído muy por encima el early draft de la especificación de Servlets 3.0. La lectura ha sido muy fácil porque tienen resaltados los cambios que han hecho respecto a la anterior versión 2.5, así que se deja leer. Creo que puede ser interesante que los resuma por aquí, por si alguien se la quiere ahorrar:


  • Anotaciones: Probablemente el cambio más grande es que ahora ya no será necesario editar los descriptores (web.xml) para crear las aplicaciones web. La nueva spec. define en su sección 8 una serie de anotaciones que se pueden utilizar para describir elementos comunes como Servlets, filtros, mapeos de URLs, parámetros de inicialización y el context listener de cada Servlet.

    Las nuevas anotaciones son @Servlet, @ServletFilter, @FilterMapping, @InitParam y @ServletContextListener. A mayores, la especificación hereda anotaciones definidas en la especificación JAX-RS (The Java API for RESTful Web Services), más concretamente @HttpMethod, @GET, @PUT, @POST, @DELETE, @HEAD. El siguiente sería un ejemplo:


    @Servlet(urlMappings={"/foo", "/bar"})
    public class SampleUsingAnnotationAttributes {
    @GET
    public void handleGet(HttpServletRequest req,
    HttpServletResponse res) {
    }
    }


    Probablemente lo que no me acabe de convencer es que la especificación deja abierta la posibilidad de mezclar las dos aproximaciones, es decir el utilizar anotaciones y el descriptor web al mismo tiempo, lo que ofrece la posibilidad de crear una especie de configuración spaghetti.

  • Fragmentos web: El segundo cambio importante son los fragmentos web. Todos los que hemos hecho aplicaciones web relativamente grandes sabemos la tendencia a crecer y crecer del fichero web.xml, lo que hace que a veces sea complicado el mantenerlo ya que no sabes donde está cada cosa, o es sencillo cometer el error de duplicar información, etc.

    Los fragmentos web permiten crear ficheros web.xml individuales que se distribuyen dentro de un fichero JAR que contendría lo que podríamos llamar una mini-aplicación web. El fichero web.xml debe colocarse dentro del META-INF y el JAR dentro del /lib. El contenedor de Servlets al arrancar la aplicación se encargará de buscar todos los fragmentos web que pueda encontrar e irá añadiendo las entradas de los diferentes web.xml individuales a la configuración de la aplicación. El siguiente es un ejemplo:


    <web-fragment>
    <servlet>
    <servlet-name>welcome</servlet-name>
    <servlet-class>WelcomeServlet</servlet-class>
    </servlet>
    <listener>
    <listener-class>RequestListener</listener-class>
    </listener>
    </web-fragment>


    Un ejemplo sería cuando quieres distribuir una consola de administración para tu aplicación web. En lugar de poner todo con la aplicación web principal, pues se podría empaquetar la consola de administración como si fuera una aplicación web independiente y distribuirla con la aplicación principal a modo de fragmento web.

    En mi opinión esta nueva funcionalidad es una buena idea que contribuye a mejorar la modularidad de las aplicaciones web. Queda abierto sin embargo el problema del punto uno de poder mezclar anotaciones con XML.

  • Procesado asíncrono. El tercer cambio importante en Servlets 3.0 es la introducción de métodos para realizar procesado asíncrono. Esto es de vital importancia para el soporte de comet de manera nativa en los contenedores web. Hasta ahora el procesado de una request es completamente síncrono. Si la request necesita bloquearse por algún recurso, el thread que está manejando esa request se bloqueará. Asimismo, si queremos mantener la request viva durante un largo espacio de tiempo haciendo streaming al cliente, la request permanecerá bloqueada. Esto hace que los contenedores web no puedan escalar apropiadamente ya que el uso de recursos no es óptimo.

    La solución propuesta en Servlets 3.0 es añadir tres nuevos métodos, suspend, resume y complete, muy al estilo de las Continuations en Jetty, y que permitirán suspender una request, reanudarla posteriormente por ejemplo desde otro thread diferente, y completarla. Es importante la nota que hacen en la especificación de que tanto el objeto request como el objeto response no son thread-safe por lo que habrá que tener mucho cuidado al controlarlos.


  • Otros. El resto de cambios, ya no tan grandes, son el añadido de nuevos métodos a la interfaz ServletContext de modo que se puedan añadir servlets y filtros programáticamente en tiempo de inicialización; el soporte de cookies HttpOnly que no están expuestas a scripting en lado del cliente, y el añadido de métodos en la request para obtener el ServletContext y la el objeto response.



En mi opinión se trata de buenos añadidos a la especificación que la mejoran bastante. Habrá que ver el tema de las anotaciones es un poco problemático como he comentado desde el punto de vista que puedes tener gente en tu equipo haciendo anotaciones y otra gente haciendo descriptores, pero bueno, al final es algo que una empresa debe controlar de todos modos con mejores prácticas, procesos, y todo esto.

Edit: Me acabo de pasar por javaHispano y mira que casualidad que hablan de lo mismo.

comments

0 Respuestas a "Repasando los cambios en Servlets 3.0"