12
AJAX en aplicaciones J2EE con DWR 1. AJAX Básicamente, AJAX (Asynchronous JavaScript and XML) es una "filosofía de desarrollo" que pretende mejorar la usabilidad de las aplicaciones web, evitando la recarga continua de diferentes páginas HTML. Cuando se ejecuta cualquier lógica de negocio, en lugar de devolver una página completamente nueva (generada en el servidor) sencillamente, se actualiza (en el cliente) el código HTML de la página actual. Figura 1. Comparación de Ajax con la filosofía tradicional La filosofía AJAX es posible gracias a dos tecnologías: 1. DHTML (Dynamic HTML).Que permite modificar, en el cliente, la estructura de la página web que se está visualizando. 2. XMLHttpRequest. A través de este tipo de objetos, se puede, desde un navegador (desde un script JS) abrir una conexión HTTP independiente con un servidor. El proceso es sencillo: un evento de usuario (por ejemplo, "onclick" en un botón), dispara la ejecución de una función JavaScript. Esta función, incluirá una llamada a un objeto XMLHttpRequest que establecerá una conexión con el servidor, solicitando la ejecución algún mecanismo similar a un procedimiento remoto (puede ser un servicio web, una Action de Struts o, simplemente, un Servlet). Finalmente, el resultado obtenido de esta llamada se plasma en la actualización (a través del API DOM) de la página web (por ejemplo, un botón podría ocultarse, podría aparecer un DIV completamente nuevo con información recibida del servidor, el contenido de una tabla se podría actualizar, etc.).

Java Intro Ajax

Embed Size (px)

Citation preview

Page 1: Java Intro Ajax

AJAX en aplicaciones J2EE con DWR

1. AJAX

Básicamente, AJAX (Asynchronous JavaScript and XML) es una "filosofía de desarrollo" que pretende mejorarla usabilidad de las aplicaciones web, evitando la recarga continua de diferentes páginas HTML. Cuando seejecuta cualquier lógica de negocio, en lugar de devolver una página completamente nueva (generada en elservidor) sencillamente, se actualiza (en el cliente) el código HTML de la página actual.

Figura 1. Comparación de Ajax con la filosofía tradicional

La filosofía AJAX es posible gracias a dos tecnologías:

1. DHTML (Dynamic HTML).Que permite modificar, en el cliente, la estructura de la página web que se estávisualizando.

2. XMLHttpRequest. A través de este tipo de objetos, se puede, desde un navegador (desde un script JS)abrir una conexión HTTP independiente con un servidor.

El proceso es sencillo: un evento de usuario (por ejemplo, "onclick" en un botón), dispara la ejecución de unafunción JavaScript. Esta función, incluirá una llamada a un objeto XMLHttpRequest que establecerá unaconexión con el servidor, solicitando la ejecución algún mecanismo similar a un procedimiento remoto (puedeser un servicio web, una Action de Struts o, simplemente, un Servlet). Finalmente, el resultado obtenido deesta llamada se plasma en la actualización (a través del API DOM) de la página web (por ejemplo, un botónpodría ocultarse, podría aparecer un DIV completamente nuevo con información recibida del servidor, elcontenido de una tabla se podría actualizar, etc.).

Page 2: Java Intro Ajax

2. Direct Web Remoting (DWR)

DWR (http://getahead.ltd.uk/dwr/) es un API que permite introducir, en las aplicaciones J2EE, la filsofía AJAXde una forma sencilla. DWR permite realizar llamadas remotas desde código JavaScript (ejecutándose en unnavegador), a objetos Java (POJOs) del servidor.

DWR no es, o al menos no pretende ser, únicamente una librería para llamadas remotas desde JavaScript. Eneste sentido, existen productos más potentes, por ejemplo, JSON­RPC. DWR es AJAX. Tan importante es larealización de llamadas a objetos del servidor como la actualización "en caliente" de la página web que semuestra al usuario.

DWR se compone de dos partes: una parte que se ejecuta en el lado cliente (en este caso, un navegador web) yotra parte que se ejecuta en el servidor (en este caso, un contenedor de Servlets).

Figura 2. Esquema del funcionamiento de DWR

2.1. DWR en el Servidor

En el lado del servidor, DWR proporciona servicios para la invocación de métodos remotos y la traducción detipos, de forma muy similar a otras tecnologías RPC.

Invocación Remota (Directa) de Métodos

  DWR proporciona un envoltorio (wrapper) para permitir la invocación de métodos de objetos Java(POJOs) desde el cliente. El sistema de RPC implementado por DWR se basa en un Servlet(uk.ltd.getahead.dwr.DWRServlet), el cual, utilizando la información que le llega a través de lapetición HTTP (HTTP Request), se encarga de instanciar los objetos necesarios y de realizar la invocacióndel método solicitado, pasándole los parámetros enviados desde el cliente. Todas estas operaciones serealizan utilizando el API de reflexión de Java.

Traducción de Tipos

  DWR puede realizar, de forma automática, traducciones de varios tipos: tipos básicos, colecciones, arraysy beans. DWR siempre intenta traducir tipos Java al tipo JavaScript más parecido. Por ejemplo, lascolecciones se pueden traducir a arrays y los beans a arrays asociativos, siendo los nombres de laspropiedades del bean los índices del array.

Page 3: Java Intro Ajax

2.1.1. Configurar el servidor

El motor de DWR es el objeto DWRServlet. En esta clase se centralizan todas las posibles funcionalidades queofrece la librería DWR: desde la generación del código JavaScript a utilizar en el cliente, hasta el marshallingde tipos (pasando, por supuesto, por la invocación a los métodos remotos).

Como cualquier otro servlet, DWRServlet debe ser declarado (y "mapeado" a alguna URL) en el fichero WEB-INF/web.xml de la aplicación web.

<servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param></servlet>

<servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern></servlet-mapping>

2.1.2. Exportar objetos Java

Cualquier clase puede exportar métodos utilizando DWR. Todas las declaraciones necesarias, tanto paraexportar métodos, como para realizar traducciones de tipos se realizan en el fichero: dwr.xml. En este ficherose realizará toda la configuración necesaria, tanto para el lado servidor como para el cliente. 

Nota

Antes de exportar métodos de objetos es muy recomendable valorar las posiblesconsecuencias (principalmente para la seguridad, pero también para la mantenibilidad delcódigo e incluso para la integridad de la propia lógica de negocio de la aplicación). Unabuena idea suele ser utilizar el patrón de diseño "FrontController": únicamente seexpondrán los métodos de determinados objetos, cuya única responsabilidad es únicamenteesa: exportar métodos que puedan ser llamados directamente por el cliente (navegador). Apartir de ahora, el concepto "Controlador DWR", se referirá siempre a este tipo de objetos.

El fichero dwr.xml tiene dos partes:

1. Declaración de mapeos de tipos. Se definen con la etiqueta <convert>. Cada una de las entradas, en elfichero dwr.xml, etiquetada como <convert> define un mapeo de tipo. Para cada tipo "no estándar"(siendo tipos estándar: int, boolean, float, String, Collections, etc.) se debe definir un mapeo.

2. Declaración de clases a exportar. Las clases (controladores DWR) cuyos métodos podrán ser llamadosdesde el cliente, se definen con la etiqueta <create>. En esta etiqueta se indica cómo se deben crear ymanejar las instancias de objetos exportados.

<dwr>

Page 4: Java Intro Ajax

<allow>

<convert converter="bean" match="es.princast.framework.core.vo.PropertyBean"/>

(1) <create creator="session" javascript="MunicipiosController"class="es.princast.sampleapp.web.dwr.MunicipiosController"> (2) </create> </allow></dwr>

(1) Para convertir un tipo Java­JavaScript se deben indicar dos parámetros (atributos de la etiqueta<convert>): 

a. La clase Java a convertir.

b. El nombre del "convertidor" (Converter) que se va a encargar de realizar el marshalling. Existenvarios convertidores incluidos en DWR (el más habitual es el converter bean, que transforma beans aarrays asociativos JavaScript). También es posible implementar convertidores propios.

Nota

Si la aplicación web está bien diseñada, entre las distintas capas de la aplicación,únicamente se producirá intercambio de objetos de tipos simples o beans (Patrón Data

Transfer Object), por lo tanto, casi siempre se utilizará el "bean converter".

(2) Mediante la etiqueta <create> se definen los objetos que se van a exportar. Los atributos necesarios son:

a. El nombre completamente cualificado de la clase Java a exportar (atributo class).

b. El nombre identificativo en JavaScript de la clase (atributo javascript). Todos los métodos de laclase se exportarán a JavaScript como funciones, con el convenio de nombrado: <NombreJavaScript>.<nombre del método>

c. El ámbito (scope) del objeto (atributo creator).

2.2. DWR en el cliente

La parte de DWR que se ejecuta en el navegador, tiene dos funciones: por un lado, sirve como stub para larealización de llamadas a los objetos del servidor, y por otro, proporciona un conjunto de funciones quefacilitan la operación sobre el código DHTML de la página web.

Stub del lado cliente

  Para poder utilizar las facilidades de llamada a métodos remotos en el servidor, es necesario importar, en elcliente, el motor DWR, escrito en el fichero engine.js. Este fichero está ubicado en el path: <servlet­dwr­path>/engine.js.

Además, DWR proporciona para cada uno de los métodos exportados por el servidor, una funciónJavaScript que actúa como stub del cliente. Los sutbs de cliente ocultan al desarrollador las complejidadesde la comunicación cliente­servidor (especialmente, el manejo del objeto XMLHttpRequest).

Page 5: Java Intro Ajax

Las funciones JavaScript, que hacen referencia a los métodos de una misma clase, se agrupan en un mismofichero .js. Cada uno de estos fichero se puede obtener siempre de la URL: <servlet­dwr­path>/interface/<nombre­clase>.js.

No es necesario escribir los ficheros stub (.js) el servlet DWRServlet se encarga de generarlos "al vuelo"utilizando la configuración que obtiene del fichero dwr.xml.

Por ejemplo, si se exporta la clase:

public class Foo {

public String doFoo() { return "foo"; }}

En la URL: <servlet­dwr­path>/interface/foo.js se encuentra un fichero de script que contiene funcionesque permitirán acceder a todos los métodos de la clase Foo. En concreto, la función " functionFoo.doFoo()" (en el cliente), permite acceder al método doFoo() de la clase Foo (en el servidor).

Para realizar llamadas a métodos del servidor, basta con utilizar las funciones de las librerias "interface".No es necesario invocar ninguna función del fichero engine.js.

Utilidades para actualizar dinámicamente la página HTML

  Además de facilitar la comunicación con el servidor, DWR incluye una biblioteca de funciones quepermiten manipular el código DHTML de la página para actualizar sus contenidos, de forma dinámica.Algunas de las operaciones que se incluyen son: actualizar el contenido de un DIV, cargar un "combo",actualizar determinados campos de texto, etc.

2.2.1. JavaScript Asíncrono

La filosofía AJAX supone que la actualización de la vista se realiza de forma asíncrona. Es decir, el usuariopuede estar centrado (leyendo, operando, escribiendo, etc.) en una parte de la página y, simulatáneamente,JavaScript está actualizando otra parte (o la misma!!).

Ya que el trabajo sobre la vista (página HTML) se realiza de forma asíncrona (multihilo), se debe tener encuenta que:

• Puede haber conflictos al actualizar simultáneamente los componentes de la página. Por ejemplo, si se envíaun formulario al servidor y, antes de que este conteste, se realiza otra operación (un listado), se puedenproducir inconsistencias en el estado de la aplicación.

• Las llamadas a métodos remotos deben ser asíncronas. Es decir, no se puede llamar directamente a unmétodo y obtener un resultado.

...data = FooRemoteClass.fooMethod(); //Llamada remota con DWRalert("Datos recibidos: "+data);...

Page 6: Java Intro Ajax

El código anterior no funcionaría, ya que se trata de una llamada síncrona. Para que una llamada remota conDWR funcione, es necesario pasarle, como parámetro, una función de callback que se encargue de procesarla respuesta del servidor. Por ejemplo:

...data = FooRemoteClass.fooMethod(processData);...

function processData(data) { alert("Datos recibidos: "+data);}

Este código realiza, de forma asíncrona, las operaciones que se pretendían ejecutar, en el primer ejemplo, deforma síncrona.

2.2.2. Actualización dinámica de la vista

Aparte de simplificar la invocación de métodos remotos (en el servidor) desde clientes ligeros, DWRproporciona un conjunto de funciones que facilitarán la actualización de la página web activa (que está viendoel usuario), de forma dinámica, utilizando JavaScript.

Estas funciones se agrupan en un fichero de scripting, que se puede obtener de la URL: <servlet­dwr>/util.js. Aligual que ocurre con otros ficheros JS servidos por el Servlet DWR, el fichero util.js se genera de formadinámica al ser solicitado (no es necesario incluir este fichero en la aplicación web).

Las funciones de utilidad van a permitir la actualización del árbol DOM de la página web activa, peroocultando, en la medida de lo posible, las complejidades del modelo de objetos DOM. Algunas de lasoperaciones más comunes van a permitir:

• Establecer un valor (o conjunto de valores) para un componente. Estas operaciones (getValue(),getValues(), setValue() y setValues()), permitirán actualizar el "valor" de un componente de lapágina. El significado del valor (o valores) vendrá determinado por el tipo de componente sobre el que seapliquen. Este conjunto de operaciones es aplicable a: campos de texto, radio­buttons, divs, etc.Prácticamente se puede utilizar con cualquier tipo de componente salvo tablas, imágenes y listas.

• Añadir / Eliminar filas de una tabla, con las funciones addRow() y removeAllRows().

• Añadir / Eliminar opciones de una lista, con las funciones addOptions() y removeAllOptions().

• etc.

El siguiente fragmento de código permite actualizar el contenido de un DIV con el resultado de la invocación aun método remoto:

<script languaje="JavaScript"> ... FooRemoteClass.getContenidoDiv(data); ...

function loadDiv(data){ DWRUtil.setValue("divId", data); }</script>

Page 7: Java Intro Ajax

<body>...<div id="divId"></div>

</body>

El código del servidor que devuelve el contenido para el DIV será:

public String getContenidoDIv() throws ServletException, IOException{ return ExecutionContext.get().forwardToString("/contenidoDiv.jsp");}

3. DWR. Un caso de uso.

Para finalizar, se presentará un ejemplo sencillo en el que se explicará, de forma detallada, cómo introducirDWR en una aplicación J2EE para solucionar, de forma elegante, una funcionalidad relativamente habitual.

En ocasiones, es necesario presentar, en un formulario, un par (o más) de listas de selección (combo­boxes)enlazadas. Estas listas de selección, tienen una relación maestro­detalle que las asocia, de tal manera que elcontenido de la segunda depende del valor seleccionado en la primera de ellas. Por ejemplo, un formulariopodría tener un campo de selección para que el usuario elija una provincia, y otro campo, de igual tipo, que lepermita elegir una población. El segundo de los campos (el de poblaciones) se debería actualizar,dinámicamente, en función del valor selecionado en el primero.

Para dar salida a este requerimiento de una forma elegante, utilizando DWR, basta con seguir los siguientespasos:

1. Diseñar la página donde se van a albergar los combo­boxes enlazados.

En este ejemplo, se trata de un formulario de inserción de datos para el envío de un pedido. Se necesitaintroducir una provincia y una localidad (que pertenecerá a dicha provincia), por lo tanto, en la páginahabrá dos componentes SELECT, tal y como se puede ver en la siguiente imagen:

El código HTML correspondiente a los dos campos de selección es el que sigue:

<form name="envioForm" method="post" action="ejemplo/dwr/action/envioAction">(1)...

<div> <label for="provincia">Provincia:</label> <select name="provincia" size="1" class="cajaTexto"id="provincia"> (2)

Page 8: Java Intro Ajax

<option value="AST">Asturias</option> <option value="MAD">Madrid</option> <option value="BCN">Barcelona</option> <option value="VAL">Valencia</option> ... </select> </div> <div> <label for="municipio">Municipio:</label> <select name="poblacion" size="1" class="cajaTexto"id="municipio">(3) </select> </div>... </form>

(1) Por simplicidad, se muestra el código HTML estático correspondiente al ejemplo. Para la generaciónde este código se puede utilizar cualquier motor de plantillas (JSP, Velocity, etc.).

(2) El maestro, en este primer paso, será una caja (combo­box) de selección estándar. Las opciones se hanañadido de forma estática, en una aplicación real se podría utilizar JSP sin problemas para sugeneración. La unica característica especial es el atributo "id" (en el ejemplo "id=provincia") que seráutilizado más adelante en los scripts.

(3) El detalle, en la página inicial, estará vacío (sin opciones). Mas adelante, se imeplementará un scriptAjax que se encargará de cargar las opciones según el valor seleccionado en el maestro. Además, aligual que en el maestro, se debe incluir un atributo "id" para su uso en los scripts (en este ejemplo"id=poblacion").

2. Implementar un objeto de negocio que permita obtener la lista de provincias que pertenecen a un municipiodeterminado:

public class MunicipiosController { public Municipio[ ] getMunicipios(String idProvincia) { return DAOFactory().getMunicipiosDAO().getMunicipios(idProvincia); } }

En este ejemplo, se ha implementado una clase: MunicipiosController, cuyo objetivo es aislar la capade negocio de la capa web. Esta clase se limita a llamar a un objeto de acceso a datos (patrón DAO) que seencargará de buscar, por ejemplo, los municipios en una base de datos.

El resultado es un array de beans de tipo Municipio, cuya definición es la que sigue:

public class Municipio {

...

public String getCodigo() {

Page 9: Java Intro Ajax

return this.codigo; }

public String getNombre() { return this.nombre; }

... }

Como se puede ver, esta clase se trata de un bean con dos propiedades: código y nombre.

3. Definir la parte del servidor

El siguiente paso será configurar la parte del servidor de DWR. Para ello, es necesario trabajar con elfichero dwr.xml, pero antes es necesario configurar el motor DWR y para ello, se debe declarar el servletDWR (DWRServlet) en el fichero web.xml (ver apartado Sección 2.1.2).

En este fichero se definirán, tanto los mapeos de tipos para el cliente, como los interfaces remotos que seexpondrán.

<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <convert converter="bean" match="mi.ejemplo.Municipio"/>(1) <create creator="session" javascript="MunicipiosController"class="mi.ejemplo.MunicipiosController">(2) </create> </allow></dwr>

(1) Utilizando la etiqueta <convert> se definen mapeos de tipos. En este ejemplo, únicamente esnecesario exportar el tipo Municipio. Para su mapeo, se utilizará el conversor (converter) "bean".Existen conversores para otros tipos: colecciones, numéricos, etc.

(2)   Los interfaces expuestos al cliente, se definen con la etiqueta <create>. En este ejemplo, se exportanúnicamente objetos de la clase mi.ejemplo.MunicipiosController. Se creará un objeto porsesión (tal como indica el atributo "creator = session"). Desde el código JavaScript, se podrá acceder aesta clase utilizando el nombre: MunicipiosController (definido por el atributo "javascript").

Una vez configurada la parte del servidor, la propia librería DWR (el DWRServlet) se encargará degenerar el stub del cliente. Este stub se puede obtener en la URL:http://localhost:8080/appEjemplo/dwr/interface/MunicipiosController.js

4. Añadir código JavaScript al cliente

Page 10: Java Intro Ajax

Para terminar, es necesario añadir, a la página JSP que se ha diseñado con anterioridad, el códigoJavaScript que le permita mantener actualizados los dos combo­boxes. La página del ejemplo quedarácomo sigue:

<script type="text/javascript"src="../../dwr/interface/MunicipiosController.js"></script>(1)<script type="text/javascript" src="../../dwr/engine.js"></script>(2)<script type="text/javascript" src="../../dwr/util.js"></script>(3)

<script type="text/javascript">(4)<!-- function init(){ (5) DWREngine.setErrorHandler(errors); update(); } function errors(message) {(6) alert("Errores "+message); }

function update() { (7) var provincia = DWRUtil.getValue("provincia"); MunicipiosController.getMunicipios(createList, provincia); }

function createList(data) { (8) DWRUtil.removeAllOptions("municipio", data); DWRUtil.addOptions("municipio", data, "codigo", "nombre"); }--></script>

...

<form name="envioForm" method="post" action="ejemplo/dwr/action/envioAction">...

<div> <label for="provincia">Provincia:</label> <select name="provincia" size="1" onchange="update();(9)class="cajaTexto" id="provincia"> <option value="AST">Asturias</option> <option value="MAD">Madrid</option> <option value="BCN">Barcelona</option> <option value="VAL">Valencia</option> ... </select> </div> <div> <label for="municipio">Municipio:</label> <select name="poblacion" size="1" class="cajaTexto"id="municipio"> </select>

<script type="text/javascript">(10) <!-- init(); -->

Page 11: Java Intro Ajax

</script> </div>... </form>

(1) Para poder acceder a los métodos exportados por el servidor es necesario importar el interface delcontrolador de la URL: <url­servlet­dwr>/dwr/interface/<controlador>.js. En este caso, como escontrolador DWR se llama MunicipiosController, la URL será: ../../dwr/interface/MunicipiosController.js.

(2) Para que el cliente pueda realizar llamadas remotas es necesario importar el "motor" de DWR. Estefichero js se encuentra siempre en la ubicación: <url­servlet­dwr>/dwr/engine.js.

(3) En este ejemplo, la librería de utilidades "util.js" se utilizará para actualizar, de forma dinámica, elcontenido del combo­box detalle. Esta librería implementa funciones auxiliares que permitenmodificar el contenido de la página web de forma relativamente sencilla y elegante.

(4) Toda la lógica de presentación que enriquece el interface está ubicada en una etiqueta <script>, deesta forma, se facilita el mantenimiento del código JavaScript (que ya de por si es bastantecomplicado).

(5) Se ha implementado una función (init()) para la precarga de valores iniciales en el componentedetalle (llamando a update()). En general, se puede utilizar esta función para cualquier operación deinicialización. En este ejemplo, además se establece un controlador de errores específico, utilizando lafunción DWREngine.setErrorsHandler().

(6) El controlador de errores es una función que se dispara en caso de que se produzca algún error en laejecución de métodos remotos. Es posible definir un controlador de errores global (como se ha hechoen el ejemplo, con la función errors()), un controlador de errores por llamada o bien, dejar que seutilice el controlador de errores por defecto.

(7) La función update() se llamará cada vez que cambie el valor seleccionado en el combo­box maestro. Elobjetivo de esta función es, ni mas, ni menos, que actualizar el componente detalle, manteniendosiempre actualizada la relación maestro­detalle. Este método se encargará de solicitar al servidor laejecución del método getMunicipios(), de la clase MunicipiosController, llamando al métododel mismo nombre implementado por el stub del cliente. Este método recibe como parámetros: a) lafunción de callback (en este ejemplo: createList()) que se encargará de gestionar el resultadocuando responda el servidor (recordar que las llamadas Ajax son asíncronas). b) Opcionalmente, elnombre de un controlador de errores específico y c) los parámetros del método remoto.

En esta función también se ha utilizado una función auxiliar (del fichero util.js) para obtener elvalor seleccionado en el componente maestro (DWRUtil.getValue()).

(8) La función createList() es el callback del cliente. Este tipo de funciones son las encargadas derecoger, de forma asíncrona, la respuesta del servidor a una invocación remota. Los callbacks recibencomo parámetro el valor devuelto por dicha invocación. En este ejemplo, el valor es una lista de beansde la clase Municipio. DWR se encargará de realizar, automáticamente el marshalling de tipos. Lalista de municipios se carga en el combo­box detalle utilizando una función de utilidad(DWRUtil.addOptions()) que permite añadir una lista de beans a un campo de tipo select. Estafunción requiere los siguientes parámetros: a) el identificador "id" del campo destino, b) la lista debeans, c) el nombre de la propiedad del bean de la que se tomarán los valores (values) de cada opcióny d) el nombre de la propiedad de los beans de la que se tomarán las etiquetas (labels) .

(9) Al componente maestro se le debe añadir un manejador para el evento "onchange". En este caso, elmanejador es la función update().

Page 12: Java Intro Ajax

(10) A continuación de los dos componentes, se ha incluido una llamada al método init() para precargarel contenido del detalle con los municipios de la primera provincia del maestro.

5. Empaquetar, desplegar y probar.

Una vez implementado todo el código, solamente queda construir el entregable, subirlo al servidor yprobarlo. Es muy importante tener activado siempre el intérprete JavaScript en el navegador. Si no hayJavaScript, no hay Ajax.

3.1. Otros posibles casos de uso

Otros posibles escenarios en los que se puede utilizar DWR (o cualquier otra tecnología Ajax) pueden ser:

• Listados maestro­detalle. Un componente típico en aplicaciones basadas en "clientes pesados" son loslistados Maestro­Detalle. En los clientes ligeros (web) este tipo de componentes se emula recargandocompletamente la página, lo que implica la renderización tanto de los datos del detalle (que pueden habercambiado) como los datos del maestro (que permanecen fijos). Con la filosofía Ajax, es posible recargarúnicamente la parte de la página correspondiente al detalle.

• Menús. Habitualmente, los menús en aplicaciones web se suelen implementar con JavaScript. Muchas veces,se utilizan componentes implementados ad­hoc. Ajax permite extender este tipo de menús, con la mejora deque el contenido de los mismos, se puede obtener, de forma dinámica, del servidor, siempre sin necesidad derecargar toda la página.

• Gestores de Ventanas (iFrames). Con Ajax es posible dividir una página en pequeños componentes (similaresa las ventanas de los programas cliente­servidor), siendo el contenido de cada uno de estos componentesactualizable, de forma independiente al resto. Sin utilizar la tecnología Ajax, este tipo de componentes seimplementan, actualmente, con iFrames o Portlets.

• Otros componentes avanzados. La filosofía Ajax permite implementar, en la parte del cliente, componentesavanzados muy similares a los disponibles en aplicaciones más pesadas. Algunos de estos componentespueden ser: árboles, tablas dinámicas, paneles con posibilidad de arrastrar componentes, barras deherramientas apilables, etc.

Acerca del autor. Ángel Retamar trabaja como arquitecto J2EE en diversos proyectos para el Principado deAsturias, entre ellos, el desarrollo del FW­PA.