Copyright (c) 2003, Daniel López Janáriz. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en http://www.javahispano.org/licencias/).
Introducción
Hoy en día las aplicaciones basadas en HTML que utilizan el navegador como cliente ligero son muy habituales. Sin embargo, el desarrollo de éstas suele ser bastante más largo y costoso que las aplicaciones tradicionales.
¿Por qué? Entre otras razones, podemos señalar que la tecnología es todavía inmadura en muchos aspectos, que en muchos casos las prisas a la hora de desarrollar aplicaciones son las que aumentan el coste y disminuyen la fiabilidad. Además, las aplicaciones para Internet suelen sufrir unos requerimientos cambiantes, sobre todo en cuanto a diseño estético, y suelen disfrutar de poco tiempo para un buen análisis y diseño, algo que sí se suele tener más en cuenta en otros tipos de aplicaciones. Por otro lado, la amplitud del mercado al cual pueden llegar nuestras aplicaciones a través de la red de redes es inmensa y por ello, debemos estar preparados para adaptarlas a nuevas situaciones como diferentes idiomas, acceso a través de distintos dispositivos, etc.
De estos hechos podemos concluir que es importante que nuestras aplicaciones sean fácilmente modificables y que puedan adaptarse a múltiples dispositivos y diferentes configuraciones, para lo cual, algunas de las técnicas más populares son la utilización de patrones tipo Model-View-Controller (MVC)[1][2] o Model-View-Presenter (MVP)[3]. Ambos patrones recomiendan dividir nuestra aplicación en componentes para que los datos (el modelo) y cómo se representan estos (las vistas) sean relativamente independientes (a través de un controlador o presentador) de forma que cambios en una parte no interfieran en la otra. El objetivo, en todo caso, es separar la lógica de la aplicación de la interfaz de usuario, aunque sin olvidar que en muchos casos la interfaz tiene sus propios procesos, comúnmente denominados lógica de presentación.
A la hora de desarrollar aplicaciones web en Java existen multitud de técnicas para implementar dichos patrones, aunque hay que tener cuidado para conseguir una separación adecuada entre la lógica y la presentación. Si no, las aplicaciones se vuelven más rígidas y difíciles de mantener. A continuación presentamos una de dichas técnicas, la utilización de XML[11][12] y XSLT[4][5][6], analizando su funcionamiento, ventajas e inconvenientes, y las experiencias llevadas a cabo con ella en el Centro de Tecnologías de la Información de la Universidad de las Islas Baleares (CTI@UIB).
Breve historia
Comenzaremos con una breve historia de la evolución del desarrollo de aplicaciones web en el CTI@UIB, desde los inicios hasta llegar a la utilización de XML y XSLT, para comprender las razones que nos han llevado a escoger dicha técnica.
El desarrollo web en el CTI@UIB comenzó alrededor de 1996, con alguna breve incursión en el mundo de los CGI, programados en C, los cuales para acceder a los datos utilizaban un precompilador propietario del fabricante de base de datos. Sin embargo, pronto se hizo evidente que dicha arquitectura (ver Figura 1) no era escalable ni mantenible a largo plazo, dada su rigidez y escasez de herramientas para controlar y gestionar el código de las aplicaciones, ya que éste se iba distribuyendo en multitud de pequeños programas en C.
Figura 1: Arquitectura de una aplicación basada en CGI
Por ello, alrededor de 1997, se decidió experimentar con un servidor de aplicaciones de reciente creación, el Web Server de Oracle(1) , que permitía crear los programas en forma de procedimientos PL/SQL agrupados en paquetes. Además, al tener los procedimientos PL/SQL dependencias en tiempo de compilación sobre el esquema de base de datos y poder agrupar éstos bajo usuarios Oracle dentro de la misma base de datos, la gestión y el mantenimiento se veía enormemente facilitada. El problema principal de esta arquitectura (ver Figura 2) era que, al generar la interfaz HTML desde los procedimientos PL/SQL, el mantenimiento de las aplicaciones, principalmente la interfaz, no era lo suficientemente flexible al necesitar un programador PL/SQL y acceso a la base de datos para cualquier cambio. En este caso específico, el usar una herramienta propietaria no era un grave problema ya que, por un lado, el lenguaje y la base de datos sí podían ejecutarse bajo múltiples sistemas operativos y la base de datos era el estándar corporativo. Por otro lado, en aquellos tiempos no había alternativas viables de las mismas características que fuesen independientes de fabricante y sistema operativo.
Figura 2: Arquitectura de una aplicación basada en el servidor de aplicaciones de Oracle y el módulo PL/SQL
Más adelante, al aparecer Java en el servidor a través de los servlets y las páginas JSP, se exploraron otras opciones que fueron desechadas por diferentes motivos. Entre éstas, podemos mencionar:
Servlets puros + JDBC. Pese a que es la opción que permite, teóricamente, un mejor rendimiento, la generación de la interfaz es bastante rígida ya que el HTML se ha de generar desde el propio código en Java. Debido a esto el mantenimiento se vuelve más complicado. Podemos ver en la arquitectura (ver Figura 3) como no existe separación entre la lógica de negocio y la generación de la interfaz.
Figura 3: Arquitectura de una aplicación basada en servlets puros + JDBC
JSP + EJB1.1. Otra opción muy popular en su momento fue la utilización de páginas JSP para generar la interfaz y EJB1.1 para implementar la lógica de negocio. Como muestra la arquitectura (ver Figura 4), con ello conseguíamos la deseada separación en capas pero sin embargo, la inmadurez de la especificación EJB conllevaba muchos problemas, como falta de portabilidad y de rendimiento en algunos casos, por lo que también fue desechada. Cabe resaltar que muchos de esos problemas han sido solventados por la nueva especificación EJB2.0, de hecho usamos EJB2.0 en algunas nuevas aplicaciones, pero las conclusiones se tomaron en su momento sobre la especificación existente.
Figura 4: Arquitectura de una aplicación basada en JSP y EJB1.1
JSP + Beans + JDBC. Esperando a que la especificación EJB madurase, una solución alternativa que se buscó fue el utilizar simples Beans con JDBC puro para implementar la lógica, sustituyendo a los componentes EJB. Pese a que con esta solución se puede separar de igual modo la lógica de la interfaz (ver Figura 5), los problemas que trae son: Por un lado, la utilización de JDBC puro dentro de nuestras clases dificulta en cierta forma el mantenimiento, ya que cambios en el esquema de la base de datos no provocan errores de compilación si no de ejecución, con lo que requieren una gran disciplina y control para prevenir este tipo de fallos. Por otro lado, dado que las librerías de tags apenas existían, la generación de la interfaz desde hojas JSP implicaba introducir código en Java en las páginas, con los problemas que ello acarrea.
Figura 5: Arquitectura de una aplicación basada en JSP y Beans con JDBC
Pese a todo, de estos experimentos se extrajeron nuevos conocimientos que nos llevaron a intentar crear una nueva arquitectura que aprovechara las ventajas de cada sistema que habíamos probado. Al mismo tiempo, en la lista de distribución jsp-interest hubo unos interesantes intercambios de opiniones entre diferentes personas(4) sobre el modelo MVC y su aplicación a través de la técnica de Servlet Controlador
(5) También se comenzaba a hablar de Java y XML como una poderosa combinación, así que nos decidimos por implementar nuestra propia solución, denominada WebLEAF, basada en Java, XML, XSL y PL/SQL. ¿Por qué? Por un lado, gracias a PL/SQL existe una dependencia entre la lógica de aplicación y el esquema de base de datos, por lo que es cambios en el esquema son fácilmente detectables en tiempo de compilación. Además, pese a ser PL/SQL un lenguaje propietario, es independiente de plataforma y se ejecuta independientemente del sistema operativo donde tengamos nuestra base de datos. Por otro lado, en lugar de inventar un lenguaje propio para la creación de interfaces a base de librerías de tags, decidimos usar XSL puesto que ya es un estándar establecido y es independiente de Java. Más adelante y para evitar dependencias del lenguaje propietario PL/SQL, se habilitó la posibilidad de utilizar otras tecnologías para implementar la lógica de negocio, entre ellas la utilización de clases EJB de tipo sesión. Dicha solución se explica en detalle más adelante y ha sido utilizada con éxito desde entonces en más de 25 aplicaciones web de pequeño y mediano tamaño, que son las requeridas por el trabajo del CTI@UIB.
Técnica básica
Una vez realizada la introducción histórica, pasamos a describir la arquitectura en la que se basan normalmente las aplicaciones que utilizan XML y XSLT para separar la lógica de la presentación. Dicha arquitectura divide, normalmente, el proceso de servir una petición en dos fases principales:
La primera fase consiste en generar un documento XML desde la lógica de la aplicación.
La segunda fase consiste en procesar el documento XML a través de una hoja de estilo XSLT de forma que el resultado de la transformación sea la interfaz deseada.
Figura 6: Diagrama básico de una arquitectura basada en XML/XSL
La complejidad puede variar según cómo se utilice esta técnica básica puesto que, por ejemplo, el documento XML puede generarse a partir de varias fuentes, o el resultado de la transformación puede no ser el resultado final, sino solo un resultado intermedio, como en el caso de generación de documentos PDF. Sin embargo, la idea común es que la lógica de aplicación y el proceso que se encarga de generar la interfaz se comuniquen a través un documento XML.
Analicemos un poco más en detalle cada una de las fases:
Generación del documento XML: En esta parte es donde suelen diferenciarse más las implementaciones, ya que un documento XML no es más que texto que sigue unas reglas de formateo y se puede generar de múltiples formas. Desde las técnicas más simples, como generar el XML concatenando cadenas de forma similar a como se generaba el HTML anteriormente, pasando por la utilización de páginas JSP como plantillas, concatenación de filtros que reciben y generan XML, caso del Cocoon..., hasta la generación de Java Beans que son traducidos automáticamente a estructuras XML, existen soluciones para todos los gustos.
Procesamiento del documento XML con XSL: La implementación de esta parte en Java es muy sencilla a través del API para transformaciones de XML (TrAX), el cual permite utilizar diferentes procesadores XSL sin cambiar el código. Para mejorar el rendimiento se suelen utilizar técnicas como el almacenar las hojas XSL preprocesadas, procesar el XML a medida que se va generando...
Ventajas e inconvenientes
Tras explicar brevemente cuál es la arquitectura básica, analicemos las principales razones para utilizar este tipo de soluciones, y cuáles son los problemas que vamos a encontrar:
Ventajas. A favor de estas técnicas podemos mencionar que:
Permiten separar totalmente la lógica de negocio de la generación de la presentación, y de su lógica. Ninguna transformación que le hagamos al documento XML afectará al sistema de información ni afectará a la integridad de los datos o de la lógica de aplicación. Esta separación también nos ayuda en la detección de errores, ya que es muy sencillo separar los errores producidos al mostrar los datos, de los producidos al generarlos. Sin olvidar que si utilizamos todo el poder de XSL, usando las plantillas adecuadamente, podemos reutilizar partes de la interfaz y aumentar la productividad y la coherencia visual de la interfaz.
El lenguaje utilizado para la generación de la interfaz, XSL, es una recomendación del World Wide Web Consortium (W3C) independiente de plataforma, fabricante y lenguaje de programación. Por ello tiene múltiples aplicaciones que no sólo se limitan a las aplicaciones web en Java. También implica que podemos encontrar implementaciones de diferentes fabricantes y escoger la que más nos convenga según nuestros requerimientos de precio, soporte, rendimiento...
La separación en dos etapas facilita enormemente la creación de aplicaciones que deben ser accedidas desde múltiples dispositivos. Partiendo del mismo documento XML podemos generar diferentes interfaces simplemente mediante la aplicación de una XSL diferente. Lo mismo se puede decir a la hora de reutilizar una aplicación con interfaces diferentes por fabricante, idioma, navegador que accede... Esta separación permite, además, la generación automática de parte del código de la aplicación, ya que la parte más difícil de generar automáticamente son las interfaces de usuario y en este caso la lógica de negocio es independiente.
Crear servicios Web utilizando esta técnica es muy sencillo, ya que se puede reutilizar la lógica de negocio y simplemente modificar la interfaz, simplificándola.
Desventajas. En contra, lo que suele mencionarse sobre este tipo de técnicas es:
Problemas de rendimiento debidos al procesamiento con XSL. Si bien es cierto que es más rápido generar directamente la interfaz o usar otro tipo de plantillas. Técnicas como la precompilación de las hojas XSL, la transformación de estas en clases Java, estilo JSP -> servlet, y el, habitualmente, escaso peso relativo de estas diferencias ante el retardo de la red y/o el acceso a bases de datos pueden minimizar el impacto de este problema. No obstante, hay que tener en cuenta que una hoja XSL mal escrita puede introducir un retardo considerable, por lo que no conviene descuidar este factor.
La creación de interfaces con hojas XSL exige unos conocimientos diferentes a la simple edición de páginas HTML. Por otro lado, el estado de las herramientas para la edición de hojas XSL, no demasiado amigables, y el cambio de mentalidad que implica XSL, ya que no es HTML pero tampoco es un lenguaje de programación como tal, dificultan el aprendizaje de estas técnicas.
Debido al punto anterior, no suele ser posible que el diseñador gráfico modifique directamente la interfaz, ya que XSL suele estar fuera de su área de conocimiento, y esto presenta un grave obstáculo en grupos de trabajo donde el diseñador ha de poder hacerlo. Sin embargo, quizá no sea tan buena idea dejar que un diseñador gráfico pueda crear y modificar las páginas web, que al fin y al cabo son la interfaz de usuario de una aplicación, sea o no web, sin el soporte de alguien versado en el diseño de aplicaciones, por lo que en otros grupos de trabajo, este punto no constituye un problema.
Implementación de una arquitectura Java-XML-XSL: WebLEAF
Una vez analizadas las características principales de la arquitectura, sus ventajas y sus inconvenientes, pasamos a explicar, como ejemplo, una implementación que integra los elementos mencionados anteriormente: WebLEAF (Light wEb Application Framework). WebLEAF es un entorno desarrollado en el CTI@UIB como soporte para la ejecución de aplicaciones web de pequeño/mediano tamaño. Este entorno implementa el modelo MVC utilizando la técnica del Servlet Controlador, y se utiliza principalmente para desarrollar aplicaciones basadas en XML/XSLT. Sus características principales son las siguientes:
Se configura un servlet, el controlador, para recibir todas las peticiones recibidas por la aplicación. Para ello se escogen uno o varios sufijos, por ejemplo «*.miapp», y se redirigen todas las peticiones que tengan dichos sufijos al servlet en cuestión
El controlador basa todo su comportamiento en ficheros de configuración, residentes en el directorio WEB-INF de la aplicación web. En dichos ficheros se especifican los pasos a seguir según la operación que se haya solicitado. Para ello la operación se especifica mediante el nombre utilizado antes del sufijo escogido. Siguiendo el ejemplo anterior una petición con URL «http://.../alta.miapp» indicaría la operación «alta».
Para responder a una petición, en la configuración debemos especificar cierta información. En el caso de las operaciones XML/XSL, lo más importante es indicar qué fuentes de datos XML hay que llamar para servir la petición y qué parámetros, en caso necesario, debemos pasar a cada una. En este caso, denominamos fuente XML a cualquier origen de datos que nos devuelva un contenido XML, como por ejemplo ficheros XML, llamadas a funciones PLSQL que devuelven XML, etc. En caso de especificar varias fuentes XML para una sola operación, normalmente sólo hay una de las fuentes XML que modifica datos y el resto son únicamente de consulta, para evitar interferencias. La idea de especificar dichas fuentes por separado es mejorar la reutilización de las consultas y permitir el uso conjunto de diferentes tipos de fuentes, como ficheros estáticos, llamadas a EJB...También debemos indicar qué hoja de estilo XSLT vamos a utilizar para procesar el resultado de juntar las respuestas de todas las fuentes XML. Si no indicamos ninguna, el XML resultante será devuelto «tal cual», lo cual es útil para pruebas en desarrollo o para implementar operaciones similares a un servicio web.
A través de la configuración también podemos indicar que, en caso de ser accedidos por un navegador en particular o en caso de ser accedidos desde un teléfono móvil, queremos usar una hoja XSLT diferente, cambiar alguna fuente de datos... También podemos cambiar esos atributos dependiendo de la localización especificada por el usuario, lo cual puede hacerse a través de una variable especial que se almacena en la sesión. De esta forma podemos adaptar la interfaz según múltiples parámetros como idioma deseado, dispositivo o navegador desde el que se accede... Incluso podemos especificar un comportamiento diferente según el sufijo que se utilice, en caso de tener varios configurados. A lo largo del tiempo hemos ido añadiendo otros pequeños detalles como éstos, pero entraremos más en profundidad en las posibilidades que brinda la configuración en el siguiente tema, al mostrar ejemplos reales de aplicaciones que las utilizan.
Un apartado importante que también permite especificar la configuración es la posibilidad de procesar las peticiones antes de acudir a las fuentes XML o de procesar el XML resultante antes de ser generada la interfaz. ¿Cuándo es necesaria esta característica? Pocas veces, pero a veces es muy útil. Por ejemplo, si programamos nuestras fuentes XML en PL/SQL y hemos de enviar un mensaje de correo electrónico, o alguna tarea similar no propia de PL/SQL, según el resultado de la consulta, podemos ejecutar una clase Java que procese el XML resultante y envíe el mensaje utilizando las facilidades que nos da este lenguaje en vez de PL/SQL. También es útil si implementamos la lógica de la aplicación usando EJB, ya que existen restricciones sobre lo que este tipo de clases pueden hacer (acceso a ficheros, manejo de conexiones de red, hilos de ejecución...)
Por último, reseñar que el Servlet Controlador se encarga además de gestionar una cache de hojas XSLT precompiladas, de las trazas, de la seguridad... ya que al centralizar el acceso a la aplicación, se facilita la gestión de todos estos aspectos.
Para aclarar el funcionamiento del sistema, sigamos paso a paso el camino para servir una petición típica:
El contenedor de servlets recibe una petición «http://.../procesar.miapp» en el contexto donde tenemos nuestra aplicación. Comprueba la configuración de éste (web.xml) y gracias al sufijo «*.miapp» detecta que el encargado de servir la petición es el Servlet Controlador.
El controlador, recibe la petición y comprueba que ese sufijo le corresponde, realiza las comprobaciones de seguridad adecuadas, prepara las trazas y añade los parámetros necesarios tales como navegador que accede, localización... Después busca en la configuración cual es la operación que corresponda a la petición, en este caso «procesar» y pasa a ejecutarla.
En caso de necesitar realizar alguna operación previa a la llamada a las fuentes XML, se suele configurar para ser ejecutada en este punto. De esta forma se puede, por ejemplo, añadir parámetros a la petición de forma que las fuentes XML los reciban.
Para ejecutar la operación, se llama a cada una de las fuentes XML que hay configuradas y se les pasan los parámetros adecuados. Para cada una de las fuentes se tiene en cuenta los parámetros de localización y navegador que accede para determinar si hay que modificar alguna característica.
En caso de querer procesar el resultado de las fuentes XML antes de generar la interfaz, se configura la operación para ejecutar las rutinas adecuadas en este punto. Aquí se pueden enviar mensajes de correo, verificar direcciones URL... y, según el resultado, modificar el XML si se considera necesario.
Como último paso, el XML resultado de todas las fuentes, quizás modificado en el punto anterior, es procesado con la hoja de estilo XSLT indicada y el resultado es devuelto al navegador.
Como se puede apreciar, el proceso en sí es relativamente sencillo y permite detectar rápidamente dónde se encuentra el fallo en caso de error, ya que las etapas de ejecución de una aplicación se pueden diferenciar claramente. A continuación mostramos gráficamente cómo sería una aplicación basada en WebLEAF utilizando fuentes XML de tipo EJB o de tipo PL/SQL.
Figura 7: Diagrama de una aplicación basada en WebLEAF
Modelo de desarrollo
Utilizando esta arquitectura, la forma de desarrollar las aplicaciones web se puede dividir en las siguientes fases:
Figura 8: Etapas en el desarrollo de una aplicacióm XML/XSL
Diseño de una maqueta HTML completa que represente la funcionalidad del producto con el máximo detalle. La maqueta sirve también para refinar el análisis de la aplicación, similar al desarrollo por prototipos, ya que se va contrastando con el usuario final.
Una vez finalizada la maqueta, se extrae la información de cada página y se realiza un modelo XML de la información necesaria para generar cada página HTML.
A partir del modelo XML y del análisis previo, se define el modelo Entidad-Relación y el esquema de base de datos necesario para contener la información de la aplicación. Además se define el «contrato XML» que es la definición de cómo, en forma de documento XML, se comunicará la lógica de negocio con la de generación de la interfaz
Se implementan las hojas de estilo XSLT para generar el HTML definido en la maqueta inicial a partir del XML del modelo.
Una vez finalizadas las hojas de estilo, se configura el entorno WebLEAF para que utilice el modelo XML (en forma de ficheros estáticos) como fuente en las operaciones XML, y para que utilice las hojas de estilo para generar la interfaz.
Al mismo tiempo, se va implementando la lógica de negocio de forma que, basándose en el esquema de base de datos diseñado, responda a los requerimientos y genere una respuesta XML basada en el modelo definido en el segundo punto
Una vez implementada la funcionalidad, se sustituyen en la configuración las referencias a los ficheros estáticos del modelo XML original por llamadas a las rutinas de la lógica de negocio que implementen la funcionalidad deseada y generen el mismo tipo de respuesta XML. Así se va convirtiendo paso a paso la maqueta estática en la aplicación dinámica.
La etapa final es de adaptación y comprobación. Al cambiar de usar ficheros estáticos a rutinas reales hay que añadir parámetros, comprobar que las diferentes respuestas dinámicas se han tenido en cuenta, como resultados de búsquedas vacíos y otros pequeños detalles.
Algunas de estas etapas se pueden simultanear en el tiempo, de forma que se pueda trabajar en equipo y en paralelo para maximizar la productividad.
Ejemplos de aplicaciones
En este apartado mencionamos algunas de las aplicaciones que hemos desarrollado en el CTI@UIB y que aprovechan las características que brinda la combinación XML/XSL.
Aplicación con múltiples idiomas (Contador de accesos a Campus Extens)
Es la primera aplicación en la que se utilizó la arquitectura WebLEAF basada en XML y XSL y donde se probaron por primera vez los conceptos en una aplicación real.
El objetivo de la aplicación es recabar y mostrar una serie de estadísticas sobre el acceso a los contenidos de las asignaturas que se imparten remotamente en la UIB. Como la interfaz es bastante simple, al diseñarla se decidió mostrar la información en varios idiomas (castellano y catalán) y probar así las posibilidades de la nueva arquitectura. Para conseguirlo se siguió una metodología muy sencilla que consiste en definir un único conjunto de hojas de estilo que generan la misma interfaz para ambos idiomas, pero que no contienen ningún texto en si. En cambio, las hojas de estilo dependen de un fichero XML externo, o varios, donde se incluyen los trozos de texto y las referencias a imágenes u otros recursos que deban ser diferentes según el idioma. Para conseguir la interfaz multilingüe se genera un fichero XML para cada idioma, y se configura el entorno WebLEAF[7] para que escoja el fichero XML adecuado según la elección del usuario.
Un poco más en detalle:
Definimos las hojas de estilo de forma que en vez de generar la interfaz usando literales, como por ejemplo «Esto es un mensaje», utilicen referencias a un fichero estático XML donde están todos los textos a cambiar(etiquetas). Así pues cambiamos el mensaje anterior por <xsl:value-of select="ETIQUETAS/@Mensaje_Uno"/>
Definimos un fichero xml (mensajes.xml) con el nombre y el valor de las etiquetas (<ETIQUETAS... Mensaje_Uno="Esto es un mensaje".../>) y configuramos las operaciones para que utilicen el fichero mensajes.xml como fuente de datos.
Para añadir otro idioma, por ejemplo catalán, creamos otro fichero mensajes_CA.xml donde escribimos las mismas etiquetas pero en catalán (<ETIQUETAS... Mensaje_Uno="Això és un missatge".../>) y configuramos un fichero de propiedades en el WebLEAF para decirle que cuando el usuario escoja el idioma «ca», use el fichero mensajes_CA.xml en vez de mensajes.xml. ¡Listo!
Hay que tener en cuenta que reutilizamos la hoja de estilo por que, al ser el castellano y el catalán idiomas similares, no es necesario modificar radicalmente la estructura, como seria el caso de combinar lenguajes que tienen distinta orientación o sentido, en cuyo caso sería más recomendable usar una hoja de estilo diferente por idioma.
Aplicación accedida desde múltiples dispositivos (Resultados de las PAAU y el proceso de preinscripción)
Se trata de una aplicación para visualizar los resultados de las pruebas de acceso a la UIB y de los resultados de preinscripción de los alumnos en las diferentes carreras.
En este caso el origen de las pruebas fue Telefónica Móviles, puesto que dicha empresa nos ofreció la posibilidad de colaborar para permitir el acceso a dicha aplicación a través de telefonía móvil usando tanto mensajería corta (SMS) como acceso a través de WAP. Decidimos aceptar la propuesta, ya que al ser una aplicación de consultas breves y en momentos determinados se adapta perfectamente a ese modelo, y diseñamos una configuración que nos permitiera reutilizar al máximo la parte ya implementada.
Dado que la aplicación ya disponía de una versión accesible a través del navegador, lo único que tuvimos que hacer fue:
Por un lado, crear dos nuevas hojas de estilo, una para crear el código WML que constituiría la interfaz a través de WAP, y otra para generar una respuesta reducida en modo texto para poder ser enviada como respuesta a los mensajes SMS.
Por otro lado, configurar el entorno WebLEAF para que usara la hoja de estilo adecuada según el tipo de dispositivo desde el que se accedía. En este caso, para distinguir entre navegadores normales y navegadores desde un móvil se utilizó la cabecera HTTP_ACCEPT. En cambio, dado que para los mensajes SMS se recibe una llamada HTTP normal y corriente, gracias al software de pasarela de Telefónica Móviles, se reservó un sufijo especial para distinguir las llamadas provenientes de mensajería corta del resto, y se configuró el entorno para que procesara la respuesta con la hoja de estilo adecuada al recibir llamadas con ese sufijo.
Como anécdota, mencionar que no se modificó ni una sola línea de código de la lógica de negocio. En aplicaciones de mayor tamaño quizá sería conveniente hacerlo en algunos casos, para optimizar el acceso y no generar demasiada información, pero en este caso no fue necesario.
También configuramos diferentes sufijos para la aplicación (según dispositivo y operador de telefonía), de forma que pudiéramos generar estadísticas de utilización de forma mucho más sencilla.
Aplicación con múltiples idiomas y múltiples vistas (The WebGuide)
«The WebGuide» es una aplicación recientemente creada en el CTI@UIB que sirve como base para la creación de repositorios de enlaces como «La guía Balears Internet» y «El Rincón Java», entre otros.
La idea es tener una aplicación que sirva como modelo y que, simplemente cambiando algunos logotipos y hojas de estilo, podamos generar fácilmente otras aplicaciones. La estrategia utilizada para conseguirlo fue similar a la de una aplicación con múltiples idiomas, pero teniendo en cuenta que cada aplicación debía ser capaz de modificar ligeramente la interfaz para adaptarla a su propio estilo, y que además cada aplicación debía poder mostrarse a su vez en diferentes idiomas. Afortunadamente, en Java el concepto de localización tiene dos parámetros: idioma y país, así que utilizamos el segundo parámetro, el país, para distinguir entre los diferentes repositorios mientras seguíamos utilizando el idioma para su uso corriente, cambiar el idioma de la interfaz.
En este caso los diferentes pasos fueron:
Crear una interfaz básica a base de hojas de estilo XSL y CSS de forma que fuese altamente parametrizable. Además, se separaron todos los mensajes en ficheros de texto aparte, se crearon varias versiones de los mismos en diferentes idiomas y se configuró el entorno para que permitiera el cambio de idioma.
También se configuró el entorno para que en función del subdirectorio usado en una petición, asignara el parámetro de localización de «país» adecuado. Por ejemplo, una petición de tipo «http://.../contexto/java/myOpp.guide» configuraba el parámetro como «java».
Se crearon hojas de estilo XSL y CSS diferentes para cada repositorio, las cuales se limitaban a importar el contenido de las genéricas y modificar las características diferentes en cada caso. Se añadieron además unos documentos XML con información específica de cada repositorio, para ser utilizados en la creación de la interfaz.
Por último, se configuró el entorno para que escogiera adecuadamente las hojas de estilo XSL según el «país». Éstas a su vez incluyen las hojas CSS adecuadas y utilizan los ficheros XML dependientes de cada repositorio, por lo que la interfaz puede ser totalmente diferentes para cada una de las diferentes vistas (repositorios) de la aplicación.
La lógica de negocio fue implementada, a diferencia de las otras aplicaciones donde se usó PL/SQL, utilizando componentes EJB 2.0 de tipo sesión. Para la persistencia se utilizaron componentes EJB 2.0 de tipo entidad, con CMP e interfaces locales.
Aplicación con generación dinámica de imágenes y versión estática (El web de la UIB) En este último ejemplo, el reto consistía en facilitar la generación automática de una versión estática de un sitio web. Dada la dificultad de mantener la homogeneidad de estilo a través de un sitio con muchas páginas, se decidió crear una aplicación que almacenara la estructura de directorios del sitio deseado, y que generara los elementos de navegación (tales como cabeceras, barras de botones...) para cada directorio. Por un lado, existía el problema de generar dinámicamente las imágenes a partir de la información de la base de datos. Por otro lado, dado el tráfico que recibe el sitio de la UIB y las relativamente escasas modificaciones que se realizan a la estructura, la relación lecturas/modificaciones aconsejaba generar periódicamente los elementos de navegación y evitar el acceso dinámico.
Ambos problemas se pudieron solucionar fácilmente gracias a la flexibilidad de la arquitectura propuesta de la siguiente forma: En el caso de las imágenes se recurrió al formato SVG (Scalable Vector Graphics)[9] que permite la representación en XML de gráficos vectoriales. Así pues, para generar las imágenes se implementó una operación que seguía los siguientes pasos:
Consultar la base de datos y generar un XML con la información necesaria para generar la imagen. Por ejemplo, la etiqueta correspondiente a un botón y el estilo a utilizar.
Utilizando una XSL, transformar el XML en un documento SVG que represente la imagen deseada, teniendo en cuenta estilos, tamaños, colores... especificados en el XML.
Por último, post-procesar el documento SVG[10] y generar un fichero .jpg, gracias a la librería Batik[8], y devolver éste.
En cambio, para generar una versión estática se utilizó una pequeña utilidad incluida en el entorno WebLEAF y que sirve precisamente para eso, para generar versiones estáticas de aplicaciones. Dicha utilidad realiza llamadas HTTP a las direcciones que se le indican y almacena el resultado en ficheros locales. Además, dicha aplicación utiliza una cabecera HTTP especial (USER_AGENT) para distinguir sus llamadas de las de un navegador normal y de esta forma, poder usar una hoja de estilo diferente durante la generación de la versión estática. Esto último es muy importante, ya que las versiones estáticas suelen modificar algunos elementos, como los enlaces a otras páginas, puesto que éstas también pueden ser estáticas. Los pasos a seguir fueron:
Crear un procedimiento que devolviera, en el formato especificado por la utilidad, la lista de páginas que se han de generar, teniendo en cuenta las modificaciones a la BDD desde la última vez que se generaron.
Crear una hoja de estilo que extendiera la hoja de estilo normal de la aplicación y simplemente modificara los enlaces a páginas dinámicas para convertirlos en enlaces a sus páginas estáticas equivalentes. Por ejemplo, un enlace del tipo «http://.../contexto/consulta.miapp?codigo=34&estado=A» podría pasar a ser «http://.../contexto/static/consulta_34A.html»
Configurar el entorno para que reconociera automáticamente las llamadas de la utilidad y que para servirlas procesara las operaciones con la XSL alternativa, en vez de con la normal.
Configurar la utilidad para que se ejecutara a intervalos regulares y que obtuviera la lista de páginas a generar a partir del resultado del procedimiento creado en el primer punto.
Este procedimiento se utiliza tanto para generar las páginas HTML estáticas como para generar las versiones estáticas de las imágenes creadas a partir de la información de la base de datos.
Conclusión
Una vez analizada la arquitectura y explicado un ejemplo de implementación y su utilización para resolver diferentes problemas, pasamos a comentar las enseñanzas aprendidas con la experiencia, y algunas conclusiones que se pueden extraer.
La separación que da realizar las aplicaciones en XML y XSL es ciertamente útil y permite la reutilización tanto de fragmentos de la lógica de la aplicación como de la lógica de presentación. Sin embargo, la parte de generación de la interfaz implica más conocimientos que la mera edición de HTML, por lo que no se adapta bien a equipos de desarrollo donde esa responsabilidad recae en un diseñador gráfico puro. En este caso pueden utilizarse las hojas de estilo como plantillas (una hoja XSL por página HTML) pero se pierde la flexibilidad y la reutilización de la técnica.
Otro punto importante es que el hecho de realizar la comunicación entre la lógica de negocio y la interfaz a través de XML permite implementar la lógica de formas diferentes. Esto nos permite elegir la técnica de implementación más adecuada (PL/SQL, EJB-CMP, EJB-Hybernate, Clases Java simples...) sin afectar a como se genera la interfaz.
La generación de la interfaz con XSL es más lenta que en otros sistemas. Sin embargo, al ser un «estándar» nos permite elegir entre diferentes implementaciones y escoger aquella que nos dé un mejor rendimiento. Además, los últimos avances, como la compilación de XSL en clases Java, y el escaso peso relativo, en la mayoría de casos, del retardo introducido por las XSL frente al retardo de la base de datos o de las comunicaciones consiguen minimizar el problema.
Pese a lo mencionado en el punto anterior, es importante de todas formas estar atento a las estructuras que utilizamos en nuestras XSL. Por ejemplo, en un caso práctico nos encontramos que usar una búsqueda de nodos en todo el documento XML (a través de «//») multiplicaba por diez el tiempo empleado en procesar un documento. También es recomendable no seguir ciegamente los criterios de que «el XML debe ser completa y totalmente independiente de la interfaz», a no ser que esté previsto que pueda ser accedido de más de una forma. En el caso de las búsquedas, por ejemplo, si sabemos que no mostraremos de golpe todos los resultados, es mejor no devolver todo el XML completo y dejar que la XSL lo recorte, sino configurar la búsqueda de forma que le podamos indicar cuantos resultados devolver en XML.
Una de las ventajas de usar XML y XSL es que facilita el mantenimiento al dividir claramente la generación de la información de la presentación. Así es más sencillo averiguar dónde se encuentran los fallos, ya que mirando el XML podemos averiguar si el problema se produjo al generar la información o al presentarla. Por ello es muy adecuado habilitar una opción que nos permita, al menos en desarrollo, poder visualizar de forma sencilla el resultado XML de nuestras operaciones antes de pasar por la XSL.
Dado que el objetivo de este documento es mostrar una implementación del desarrollo de aplicaciones usando Java, XML y XSLT, no se ha hecho una comparación con otros modelos de desarrollo ni sus posibles implementaciones, como entornos del tipo Struts, SiteMesh o similares, ya que alargaría demasiado el documento. Respecto a la cuestión de por qué escogimos desarrollar nuestro propio entorno, de forma breve podemos decir que en el momento de comenzar a implementar WebLEAF no se podía escoger entre desarrollar un entorno propio o utilizar alguno ya establecido, ya que no había ninguno. Más adelante, las ventajas que proporciona tener una solución simple, que se adapta perfectamente al modelo de desarrollo que se utiliza y sobre la cual tienes un control absoluto nos han llevado a continuar con una implementación propia, pese a las desventajas de tener que mantenerla. Sin embargo, no descartamos cambiar a un producto externo si encontramos alguno adecuado, siempre que el cambio nos proporcione mas ventajas que inconvenientes. Pero ese sería tema para otro trabajo.
Como último apunte, resaltar que, desde nuestro punto de vista, el uso de XML y XSL no es la solución definitiva a todos los problemas del desarrollo de aplicaciones web, si no una de las múltiples alternativas con las que se pueden afrontar este tipo de proyectos. Cada alternativa tiene sus ventajas y sus inconvenientes, se adapta mejor o peor a unos grupos de trabajo, o a diferentes tipos de proyectos, etc. Eso es lo que se ha de valorar en cada caso, para después poder utilizar la solución más acertada conociendo tanto las ventajas, para aprovecharlas al máximo, como los inconvenientes, para minimizar sus efectos. Nuestra intención con este documento era profundizar en la utilización de XML y XSL para que después de leerlo, puedan realizar mejor la valoración de dicha técnica.
Notas
(1) Más tarde conocido como Web Application Server (WAS), Internet Application Server (IAS), Oracle Application Server (OAS)...
(4) Entre dichas personas se encontraba también Craig McClanahan, creador de un conocido entorno de desarrollo de aplicaciones web en Java (Struts) que implementa MVC a través de un Servlet Controlador.
(5) Técnica a través de la cual todas las peticiones a una aplicación web en Java se redirigen a un único servlet que se encarga de servir la petición según los parámetros y el formato del URL de la petición.
Recursos
[1]
Designing Enterprise Applications with the J2EETM Platform, Second Edition,
Inderjeet Singh, Beth Stearns, Mark Johnson, Enterprise Team
,
Addison-Wesley Pub Co
, ISBN
0201787903
[12] Extensible Markup Language (XML) 1.0 (Second Edition), W3C Recommendation 6 October 2000,
http://www.w3.org/TR/REC-xml
Acerca del autor
Daniel López Janáriz Daniel trabaja en el Centro de Tecnologías de la Información de la Universidad de las Islas Baleares (CTI@UIB.ES) como coordinador del desarrollo web. Además de programar en Java, diseñar aplicaciones web y administrar el Rincón Java, también le gusta invertir el tiempo con otras cosas importantes como salir con la novia, los amigos, ir al cine, leer... No todo es informática en la vida.
Presentado en el: I. Congreso javaHispano, celebrado los días 22 y 23 de Octubre de 2003