Está en la página 1de 48

CURSO DE DIRECT WEB REMOTING (DWR)

Gua sobre DWR con Ejemplos


DWR (Direct Web Remoting)es una librera Javascript que
permite el uso de Ajax (Asynchronous JavaScript and XML) de
forma mucho ms simple (Este artculo asume que se
entiende los conceptos de Ajax, y de Java).
DWR es una librera ms orientada a apoyar la integracin,
que a apoyar la parte grfica, de hecho si se buscan Widgets
(objetos grficos) esta no es la librera, pero por otro lado lo
fuerte de DWR es que permite publicar fcilmente
funcionalidad de clases Java para accederlas va Javascript.
Luego si nuestra funcionalidad o lgica de negocio est en
Java, DWR es una de las mejores opciones para aprovecharla,
ya que usar una clase Java que tenemos en un servidor de
aplicaciones va Javascript es tan fcil como definir un archivo
de configuracin en el servidor.
Ahora si se requiere adems darle una interfaz ms rica (rich
interface) a los usuarios, es bueno combinar DWR con otras
libreras Ajax como YUI (Yahoo User Interface), JQuery,
Prototype, Scriptaculous, Dojo, o Spry.
Con Ajax se terminan las paginas JSP, o ASP (o deberan
terminarse), porque Ajax solo necesita Javascript y HTML para
la parte de presentacin, esto lo explicaremos mejor en otro
artculo, pero por ahora crannos. Y con DWR ni siquiera son
necesarios los Servlets, esto en el sentido de que no se
necesitan desarrollar servlets para implementar la lgica de
negocio, porque DWR si internamente est basado en
Servlets, en otras palabras gracias a DWR no necesitamos

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


implementar nuestros servlets sino solo necesitamos clases
Java (POJO).
Si se conoce la tecnologa Axis, que permite publicar clases
Java como Webservices, este es el smil para publicar clases
Java como objetos Ajax (objetos Javascripts), de hecho es
muy fcil publicar con DWR un servicio realizado para Axis.
Incluso las buenas prcticas o blueprints de Axis para publicar
clases como Webservices se aplican totalmente para publicar
clases para Ajax., ya que hay que tener los mismos cuidados
en cuanto a seguridad y manejo de desempeo
(performance).
La definicin oficial de DWR es:
DWR permite a Javascript (en un Browser) interactuar con las clases Java
en un Servidor, y ayuda a manipular las pginas Web con los resultados.

S, porque otra caracterstica importante de DWR es que


ofrece funcionalidades Javascript que permiten fcilmente
manipular el HTML de la pgina: como obtener los datos de
un formulario (HTML Form), o de cualquier otro tag HTML, o
setear fcilmente los valores de los tags HTML, adems
aporta facilidades para clonar tags, lo que permite por
ejemplo crear nuevas filas (rows) en una tabla (HTML Table),
muy til para mostrar una consulta. DWR no nos provee
ningn objeto grafico pre-hecho, pero si nos permite la
flexibilidad para hacer cualquier cosa con el HTML.
Bueno basta de conceptos y vamos directo al cdigo.
Esta gua cumple con lo siguiente:

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Es lo ms simple posible, tiene lo justo y necesario para
entender el concepto principal de DWR, y como funciona.
Esta actualizado, otros ejemplos estn basados en
versiones anteriores de DWR.
Esta completo, otros ejemplo ponen solo parte del
cdigo.
Usa clases y colecciones de clases (Collection) como
parmetros de entrada y parmetros de salida, que es lo
que tpicamente se va a usar en un sistema real, otros
ejemplos usan datos ms bsicos. De esta forma
tambin se muestra como se manejan las colecciones y
las clases en Javascript.

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


DWR en 10 Simples Pasos
1. Lo primero es bajar DWR de la direccin mostrada a
continuacin: (http://getahead.org/dwr/download), basta
bajar solo la librera (dwr.jar).
2. Luego hay que modificar el archivo web.xml, este se
encuentra bajo el directorio WEB-INF, ejemplo:
\dwrEasy\WEB-INF, se debe incluir las definiciones de los
servlets que atienden los requerimientos DWR-AJAX.

Web.xml:
01.< ?xml version="1.0" encoding="UTF-8"?>
02.< !DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
03.<web_app>
04. <display_name>dwrEasy</display_name>
05. <servlet>
06.
<servlet_name>dwr-invoker</servlet_name>
07.
<display_name>DWR Servlet</display_name>
08.
<description>Direct Web Remoter Servlet</description>
09.
<servlet_class>org.directwebremoting.servlet.DwrServlet
</servlet_class>
10.
<init_param>
11.
<param_name>debug</param_name>
12.
<param_value>true</param_value>
13.
</init_param>
14. </servlet>
15. <servlet_mapping>
16.
<servlet_name>dwr-invoker</servlet_name>
17.
<url_pattern>/dwr/*</url_pattern>
18. </servlet_mapping>
19.</web_app>

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

3. A continuacin se debe implementar la clase Java que va a


ofrecer los servicios, esta basta que sea un clase Java simple
(POJO), con un constructor sin parmetros, y donde cada
mtodo de la clase es un potencial servicio Ajax.
Esta clase va a estar del lado del servidor de aplicaciones
(ejemplo: Tomcat, JBoss, o Websphere) no tiene que ser
necesariamente un servidor J2EE.
La Clase EasyService, se muestra en la Siguiente pgina:

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


EasyService.java:
01.package com.soaagenda.services;
02.
03.import com.soaagenda.valueobjects.*;
04.
05.public class EasyService {
06.public EasyService() {
07.}
08.
09.public EasyResponse getProducts(EasyParameter parametersX){
10.EasyResponse responseX= new EasyResponse();
11.
12.
13.// si parametros vacios devuelve error, error if empty parameters
14.if (parametersX==null || parametersX.getClientID()==null ||
parametersX.getClientID().length()< =0){
15.responseX.setErrorCode(10001);
16.responseX.setErrorDescription("Debe indicar ID Cliente. Give us Client
ID");
17.return responseX;
18.}
19.
20.//crea lista productos del cliente, fill the client product list
21.//para ejemplo en duro, for the example fixed data
22.Product[] productsListX= new Product[2];
23.
24.Product productX= new Product();
25.productX.setBarCode("0001");
26.productX.setName("Tarjeta Visa, Visa Credit Card");
27.productsListX[0]= productX;
28.
29.productX= new Product();
30.productX.setBarCode("0002");
31.productX.setName("Tarjeta American Express, American Express Credit
Card");
32.productsListX[1]= productX;
33.
34.//respuesta exitosa, sucessfull response
35.responseX.setErrorCode(0);
36.responseX.setErrorDescription("Consulta Banco Exitosa, Succesfull Bank
Query");
37.responseX.setProducts(productsListX);
38.
39.return responseX;
40.}
41.}

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Este ejemplo simula una consulta de los productos
bancarios de un cliente como Tarjetas de Crdito (VISA,
Master Card, Dinners, American Express), Cuentas
Corrientes, o Crditos de Consumo, para esto se le pasa
como parmetro un objeto que tiene el ID del cliente, y
el tipo de producto a consultar, el servicio (o mtodo)
devuelve otra clase con el cdigo de error, mensaje de
error, y la lista de productos (un arreglo de clases
producto).
4. Tambin hay que definir las clases de datos (Value Objects)
que va a utilizar el servicio, esta clases deben ser javabeans
(atributo privados, con getters y setters):
EasyParameter.java: define los parmetros de entrada del
servicio.
01.package com.soaagenda.valueobjects;
02.
03.public class EasyParameter {
04.private String clientID;
05.private String productType;
06.public EasyParameter() {
07.}
08.
09.public void setClientID(String clientID) {
10.this.clientID = clientID;
11.}
12.
13.public void setProductType(String productType) {
14.this.productType = productType;
15.}
16.
17.public String getClientID() {
18.return clientID;
19.}
20.
21.public String getProductType() {
22.return productType;
23.}
24.}

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


EasyResponse.java: define la estructura para los resultados
del servicio.
01.package com.soaagenda.valueobjects;
02.
03.public class EasyResponse {
04.private int errorCode;
05.private String errorDescription;
06.private Product[] products;
07.
08.public EasyResponse() {
09.}
10.
11.public void setErrorCode(int errorCode) {
12.this.errorCode = errorCode;
13.}
14.
15.public void setErrorDescription(String errorDescription) {
16.this.errorDescription = errorDescription;
17.}
18.
19.public void setProducts(Product[] products) {
20.this.products = products;
21.}
22.
23.public int getErrorCode() {
24.return errorCode;
25.}
26.
27.public String getErrorDescription() {
28.return errorDescription;
29.}
30.
31.public Product[] getProducts() {
32.return products;
33.}
34.}

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Product.java: define la estructura de un producto.
01.package com.soaagenda.valueobjects;
02.
03.public class Product {
04.private String barCode;
05.private String name;
06.public Product() {
07.try {
08.jbInit();
09.} catch (Exception ex) {
10.ex.printStackTrace();
11.}
12.}
13.
14.private void jbInit() throws Exception {
15.}
16.
17.public void setBarCode(String barCode) {
18.this.barCode = barCode;
19.}
20.
21.public void setName(String name) {
22.this.name = name;
23.}
24.
25.public String getBarCode() {
26.return barCode;
27.}
28.
29.public String getName() {
30.return name;
31.}
32.}

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


5. Vamos a indicarle a DWR que clases vamos a publicar para
Javascript (Ajax), esto se hace en el archivo dwr.xml, y
tambin corresponde a un esquema de seguridad porque
podemos llegar a especificar solo que mtodos de una clase
queremos exponer, y que atributos.
Para nuestro ejemplo vamos a publicar toda la clase
servicio (com.soaagenda.services.EasyService), es decir
todos sus mtodos, y todas las clases de datos
(com.soaagenda.valueobjects.*).
dwr.xml
01.< ?xml version="1.0" encoding="UTF-8"?>
02.< !DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web
Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
03.<dwr>
04.<allow>
05.<!-- define la clase de servicios que se va a publicar mediante
DWR -->
06.<!-- defines the service class to share across DWR -->
07.<create creator="new" javascript="EasyService">
08.<param name="class"value="com.soaagenda.services.EasyService"/>
09.</create>
10.<!-- define las clases de datos que utiliza el servicio -->
11.<!-- defines the data classes to share across DWR -->
12.<convert converter="bean"match="com.soaagenda.valueobjects.*"/>
13.</allow>
14.</dwr>

10

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


6. Ahora si compilamos las clases, y publicamos nuestro ejemplo
Web (deploy), DWR nos presta una utilidad para probar que
todo anda bien, esta se accede desde un Browser, en el path
/dwr/,
dentro
de
nuestro
sitio
(ejemplo:
http://localhost:8028/dwrEasy/dwr/)

Seleccionado el servicio, nos aparece primero las libreras


javascript necesarias para implementar una pgina Web,
luego la lista de servicios (mtodos de las clase servicio) a los
que tenemos acceso (getProducts).

11

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

Como no restringimos los mtodos de la clase, incluso


nos aparecen los mtodos que hereda por ser una clase
Java (como hashCode, getClass).
Si presionamos el botn Execute, ejecuta el servicio, y
para el caso de nuestro ejemplo este retorna un error
Debe indicar ID Cliente, lo que est bien porque no le
hemos indicado parmetros de entrada, con esto
sabemos que todo anda bien, porque esa respuesta la da
nuestra clase que est en el servidor, es decir,
ejecutamos desde Javascript (Browser) una clase que
est del lado del servidor, eso es Ajax y DWR!!.

12

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


7. Lo siguiente es crear nuestra pgina HTML que va a consultar
los resultados y mostrarlos, esta pgina es sumamente
simple, tiene un formulario (Html Form), en realidad solo
tiene las variables del form, porque ya no es necesario el tag
<form> (recuerden que con Ajax la forma de hacer request
al Server cambia, ahora es asncrona), y tiene una tabla (html
table) para mostrar el resultado.

13

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


dwrEasyPage.html
01.< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
02.<html xmlns="http://www.w3.org/1999/xhtml">
03.<head>
04.<title>Editable Table Demo</title>
05.<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
06.<script
type='text/javascript'src='/dwrEasy/dwr/interface/EasyService.js'></script>
07.<script type='text/javascript' src='/dwrEasy/dwr/engine.js'></script>
08.<script type='text/javascript' src='/dwrEasy/dwr/util.js'> </script>
09.<script type="text/javascript" src='dwrEasyJS.js'> </script>
10.</head>
11.
12.<body>
13.<h1>Easy DRW Demo</h1>
14.<h3>Buscar / Search</h3>
15.
16.<table>
17.<tr>
18.<td>ID Cliente / Client ID:</td>
19.<td><input name="formClientID" type="text"id="formClientID" size="15"/></td>
20.</tr>
21.<tr>
22.<td>Tipo Producto / Product Type</td>
23.<td><input name="formProductType" type="text"id="formProductType"
size="15"/></td>
24.</tr>
25.<tr>
26.<td colspan="2" align="right">
27.<input type="button"
value="OK"onclick="javascript:submitProductsRequest()"/>
28.</td>
29.</tr>
30.</table>
31.
32.<h3>Productos / Products</h3>
33.<p>Respuesta / Response:
34.<input name="serviceResponse" type="text"id="serviceResponse" size="50"/>
35.</p>

Contina
.

14

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


36.
37.<table border="1">
38.<thead>
39.<tr>
40.<th>Codigo / BarCode</th>
41.<th>Nombre / Name</th>
42.</tr>
43.</thead>
44.<tbody id="myTable">
45.<tr id="myPattern" style="display:none">
46.<td>
47.<span id="codePattern">code example</span></td>
48.<td>
49.<span id="namePattern">name example</span></td>
50.</tr>
51.</tbody>
52.</table>
53.</body>
54.</html>

Si analizamos el cdigo, lo primero es la referencia a las


libreras
Javascript
(EasyService.js,
engine.js,
util.js), estas fueron generadas por DWR, luego
aparece la librera (dwrEasyJS.js) que ya es propietaria
(custom), y que debemos construir para realizar la lgica
de interaccin (esta redescribe a continuacin).
Luego aparecen las variables del formulario a solicitar
(formClientID, formProductType), y el botn que define
la accin de consulta, ejecuta la funcin Javascript
javascript: submitProductsRequest(), esta funcin es la
que se encuentra definida en la librera (dwrEasyJS.js),
la cual vamos a tener que construir.
Despus viene
(myTable).

15

la

tabla

que

mostrar

los

datos

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Podemos ver que hay ciertas caractersticas especiales
en el cdigo Html, estas le van a servir a DWR para
encontrar donde obtener, o donde mostrar los datos:
Los Id de los tags html le sirven a DWR para manejar
los datos:
Los id formClientID, formProductType le
permiten encontrar loas parmetros de entrada.
El id myTable, le servir para saber que tabla
limpiar.
El id myPattern, le indicar a DWR que filas
(rows) debe clonar para mostrar cada registro de
producto de la lista, como es un patrn en
principio va oculto (style=display:none).
Los id codePattern, namePattern servirn para
qeu DWR sepa dnde colocar los datos de cada
producto, en este caso se usan tags <span>.
Como vemos esta pgina es solo Html, y Javascript, que
hermosamente simple, nada de JSP, ni de ASP, una
pgina que se puede publicar en cualquier servidor Web.
8. Lo que sigue es la librera Javascript propia.

16

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


dwrEasyJS.js
01.function submitProductsRequest() {
02.var idX=dwr.util.getValue("formClientID");
03.var typeX=dwr.util.getValue("formProductType");
04.
05.var parametersX={clientID:idX,productType:typeX};
06.
07.EasyService.getProducts(parametersX,showProducts);
08.
09.}
11.
12.function showProducts(responseX) {
13.
14.// borro filas excepto el patron, delete rows except pattern
row
15.dwr.util.removeAllRows("myTable", { filter:function(tr) {return
(tr.id != "myPattern");}});
16.
17.if (responseX.errorCode!=0){
18.alert('Error: '+responseX.errorDescription);
19.return;
20.};
21.var productsX=responseX.products;
22.var lengthX=productsX.length;
23.var itemProductX;
24.
25.if (lengthX==0){
26.alert('No hay productos, Cant find products');
27.return;
28.};
29.
30.dwr.util.setValue("serviceResponse",
responseX.errorDescription);
31.
32.var id="00";
33.for (var i=0 ; i<lengthx ; i++) {
35.temProductX= productsX[i];
36.id="00"+i;
37.dwr.util.cloneNode("myPattern", { idSuffix:id });
38.dwr.util.setValue("codePattern" + id, itemProductX.barCode);
39.dwr.util.setValue("namePattern" + id, itemProductX.name);
40.$("myPattern" + id).style.display = "";
41.}
42.}

17

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


9. Esta librera tiene dos funciones: submitProductsRequest la
que obtiene los parmetros de entrada y ejecuta el servicio
correspondiente (clase Java EasyService.getProducts() va
DWR), y la funcin que muestra los datos (showProducts).
Finalmente hay que subir las pginas (Deploy) en el sitio
Web, quedando el proyecto con la siguiente estructura:

Ejecutamos la pagina de prueba dwrEasyPage en


nuestro
Browser
(ejemplo
http://localhost:8028/dwrEasy/dwrEasyPage.html),
ponemos un dato en ID Cliente, presionamos OK, y
listo!, nuestra primera aplicacin Ajax-DWR.
10.

18

The End

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


OTROS EJEMPLOS
AJAX es un acrnimo que significa "Asynchonous JavaScript
XML".
En si, AJAX es una tcnica de programacin web mediante la
cual una pgina web puede intercambiar informacin con el
servidor en forma asincrnica, de manera tal que la pgina
puede actualizarse sin necesidad de ser recargada. El cliente
(browser con la pgina web) y el servidor mantienen una
comunicacin asincrnica y en background.
AJAX es netamente JavaScript pero en este captulo vamos a
explicar un framework que permite invocar desde JavaScript
(browser, cliente) mtodos remotos, en el servidor
implementados en Java.

Manipulacin de Objetos HTML


Como vemos, DWR resuelve de manera extremadamente
simple la invocacin remota de mtodos entre la pgina HTML
(o JSP) y la clase Java que los implementa. Por lo tanto la
mayor complejidad est dada en poder actualizar
dinmicamente el contenido HTML con la informacin que
llega desde el servidor.
Para esto DWR provee una librera de funciones JavaScript
llamada: util.js. Veremos algunos ejemplos de cmo
actualizar contenido dinmicamente utilizando esta librera.

19

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Combos Dependientes
En este ejemplo veremos cmo actualizar el contenido de un
combo dependiendo de lo que el usuario selecciona en otro
combo.
Para esto programamos la siguiente clase que basicamente
proveer dos mtodos:

Collection obtenerArtistas();
Collection obtenerDiscos(String artista);

Es decir: el primer mtodo retornar una Collection de Strings


con los nombres de los artistas "registrados en una base de
datos" y el segundo mtodo, dado un nombre de artista
retornar todos los discos de ese artista que "tenemos
registrados".
Para simplificar, los datos los hardcodearemos en una
Hashtable.

CatalogoCD.java
1:
2:package test;
3:import java.util.*;
4:
5:public class CatalogoCD
6:{
7:
private Hashtable artistas;
8:
9:
public CatalogoCD()
10:
{
11:
artistas=new Hashtable();
12:
_cargarInformacion();
13:
}
14:

20

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:}
59:

21

// retorna una Collection de Strins con los


// artistas que tenemos registrados
public Collection obtenerArtistas()
{
Vector v=new Vector();
for(Enumeration e=artistas.keys()
;e.hasMoreElements();)
{
v.add(e.nextElement());
}
return v;
}
// dado un artista, retorna una Collection de
// Strings con los titulos de los discos del
// artista especificado
public Collection obtenerDiscos(String artista)
{
return (Collection) artistas.get(artista);
}
// todo harcodeado...
private void _cargarInformacion()
{
Vector v1=new Vector();
v1.add("Please Please Me");
v1.add("Abbey Road");
v1.add("Magical Mistery Tour");
artistas.put("The Beatles",v1);
Vector v2=new Vector();
v2.add("Demasiado Ego");
v2.add("La Hija de la Lagrima");
v2.add("Say No More");
v2.add("Kill Gil");
artistas.put("Charly Garcia",v2);
// sexo Ibiza Locomia...!
Vector v3=new Vector();
v3.add("A Ibiza con Locomia");
v3.add("Abanicos Por Doquier!");
artistas.put("Locomia",v3);
}

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Para registrar la clase como servicio en DWR tenemos que
agregar las siguientes lneas en el archivo dwr.xml.
1:
2:
3:
4:
5:

<create creator="new" javascript="CatalogoCD">


<param name="class" value="test.CatalogoCD"/>
</create>

Ahora vamos a:
http://localhost:8080/[YOUR-WEBAPP]/dwr/test/CatalogoCD

Para ver los scripts que debemos incluir en la pgina JSP.

Y ahora veamos la pgina JSP:

22

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


discos.jsp
1:
2:<html>
3:
<head>
4:
<script
5:
type='text/javascript'
6:
src='/TestAjax/dwr/interface/CatalogoCD.js'>
7:
</script>
8:
<script
9:
type='text/javascript'
10:
src='/TestAjax/dwr/engine.js'>
11:
</script>
12:
<script
13:
type='text/javascript'
14:
src='/TestAjax/dwr/util.js'>
15:
</script>
16:
17:
<script>
18:
function obtenerArtistas()
19:
{
20:
CatalogoCD.obtenerArtistas(function(data){
21:
dwr.util.removeAllOptions("cbArtista");
22:
dwr.util.addOptions("cbArtista", data);
23:
obtenerDiscos();
24:
});
25:
}
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

function obtenerDiscos()
{
var art = dwr.util.getValue("cbArtista");
CatalogoCD.obtenerDiscos(art,function(data)
{
dwr.util.removeAllOptions("cbDisco");
dwr.util.addOptions("cbDisco", data);
});
}
</script>
</head>

38:
39:
<body>
40:
<input type="button"
41:
value="Cargar"
42:
onclick="obtenerArtistas()"
43:
<select id="cbArtista"
44:
onChange="obtenerDiscos()"
45:
<select id="cbDisco" />
46:
</body>
47:</html>
48:

23

/>
/>

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Como vemos, la pgina en si comienza a partir de la lnea 39.
Tenemos dos select (combos), uno con id="cbArtista" y el
otro con id="idDisco" y un button.
En el evento onclick del botn invocamos a la funcin
obtenerArtistas, y en el evento onChange del combo de
artistas invocamos a la funcinobtenerDiscos.
Analicemos entonces la funcin obtenerArtistas (que se
encuentra a partir de la lnea 18).
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:

function obtenerArtistas()
{
CatalogoCD.obtenerArtistas(function(data){
dwr.util.removeAllOptions("cbArtista");
dwr.util.addOptions("cbArtista", data);
obtenerDiscos();
});
}

La funcin invoca a CatalogoCD.obtenerArtistas pasndole


una funcin callback en la que primero removemos todos los
items del combo y luego seteamos en el combo de artistas la
coleccin que retorna el mtodo Java. Por ltimo invocamos a
la funcin obtenerDiscos para cargargar los discos del artistas
que qued seleccionado.
El cdigo de la funcin obtenerDiscos est a partir de la lnea
27 y lo podemos ver a continuacin.

24

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:

function obtenerDiscos()
{
var art = dwr.util.getValue("cbArtista");
CatalogoCD.obtenerDiscos(art,function(data)
{
dwr.util.removeAllOptions("cbDisco");
dwr.util.addOptions("cbDisco", data);
});
}

En esta funcin tomamos el valor que se encuentra


seleccionado en el combo de artistas y lo asignamos a la
variable
art.
Luego
invocamos
a
la
funcin
CatalogoCD.obtenerDiscos pasndole art y una funcin
callback dentro de la cual borramos los items del combo de
discos y seteamos en dicho combo la coleccin que retorna el
mtodo Java.

El resultado ser:

25

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

AJAX con DWR en NetBeans 6.1


Una de las bibliotecas ms fciles que he visto para
programar en AJAX es el Direct Web Remoting - DWR.
En este captulo veremos algunas de sus caractersticas que
nos ayudar a tener aplicaciones enriquecidas con Ajax. Para
ello usaremos:
1.
2.

NetBeans 6.1
DWR

Instalando DWR en NetBeans


La biblioteca DWR consta nicamente de un archivo .jar. Este
lo podemos descargar de aqu:
http://getahead.org/dwr/download.

Guardaremos el archivo en una carpeta que ser destinada


para las bibliotecas de los proyectos. Yo, en Windows, lo
guardo en d:\proys\lib\DWR, y en Linux lo guardo en
~/proys/lib

Adicionalmente DWR necesita de la biblioteca


commons-logging.
Esta la puedes descargar de aqu:
http://commons.apache.org/downloads/download_logging.cgi

26

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Descomprimamos el archivo descargado de commons-logging
en la misma carpeta lib.
Entramos a la opcin Tools > Libraries:

Hacemos clic en "New Library" para crear una nueva


biblioteca, y llamaremos DWR.

Clic
en
OK.
Ahora
correspondientes.

27

agregamos

los

archivos

.jar

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Hacemos clic en Add Jar/Folder y seleccionamos el archivo
commons-logging-1.1.1.jar y dwr.jar

Clic en OK parar cerrar la ventana.

El proyecto Web
Ahora crearemos un aplicacin web, que no usar ningn
framework. Ser una aplicacin totalmente "simple". La
llamaremos DwrSamples.

En las propiedades del proyecto web creado, entramos a sus


propiedades haciendo clic derecho sobre el cono del proyecto,
y seleccionamos "Properties". En esta ventana seleccionamos
del margen izquierdo la categora "Libraries". Luego
agregamos la biblioteca DWR haciendo clic en el botn "Add
Library". Despus de esto, deber lucir as:

28

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

Crearemos una clase a la que llamaremos Calculadora y


estar en el paquete logica. Esta clase, bsicamente, tendr
los mtodos que realizarn las operaciones de manera
asncrona.

package logica;
public class Calculadora {
public int sumar(int a, int b) {
return a + b;
}
public int restar(int a, int b) {
return a - b;
}
}

29

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Ahora, necesitamos que esta clase sea leble por DWR, por lo
que usaremos anotaciones para "publicar" la clase como
objeto javascript, pero slo publicaremos el mtodo sumar()
para que sea ajax. Usaremos la anotacin de DWR
@RemoteProxy para la clase Calculadora, y @RemoteMethod
para el mtodo sumar(). Deber lucir as:

package logica;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
@RemoteProxy
public class Calculadora {
@RemoteMethod
public int sumar(int a, int b) {
return a + b;
}
public int restar(int a, int b) {
return a - b;
}
}

Ahora, abrirmos el archivo web.xml (podemos presionar


Shift + Alt + O para abrir el buscador de archivos y escribir
web para que nos seleccione el archivo que estamos
buscando). En la barra superior hacemos clic en el botn
"Servlets" para visualizar los servlets de nuestra aplicacin.
Una vez all, hacemos clic en el botn "Add Servlet".

30

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


El nuevo servlet que crearemos, le pondremos el nombre
"DWR", la clase del servlet ser:
"org.directwebremoting.servlet.DwrServlet", y el patrn URL
ser "/dwr/*", es decir, este serlet responder las peticiones
en la direccin "/dwr/". Deber lucir esta ventana as:

Hacemos clic en "OK". Luego, agregaremos un parmetro de


inicio. Hacemos clic en el botn "Add.." de la seccin
"Initialization Parameter".

El parmetro de inicio lo llamaremos classes, y tendr una


clase llamada logica.Calculadora.

31

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

Clic en OK, y deber lucir as la ventana de los servlets.

32

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


O si lo prefieres en xml, el archivo web.xml deber lucir as.

Ahora, crearemos nuestra interfaz.


index.jsp, le pondremos un formulario:

Abrimos

el

archivo

<h2>Calculadora</h2>
<form action="">
Valor 1: <input type="text" name="valor1" id="valor1"/><br/>
Valor 2: <input type="text" name="valor2" id="valor2"/><br/>
<input type="button" value="Sumar" onclick="sumar()"/><br/>
Resultado:<div id="suma"></div>
</form>

33

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Nota que el botn no es un submit, sino un tipo "button".
Tampoco hay que olvidar los atributos id de los tags. Estos
nos ayudarn a identificar un tag en toda la pgina.

Ahora, necesitamos importar las bibliotecas de DWR. Para


ello, agregamos las siguientes lineas en la cabecera del jsp.

<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/interface/Calculadora.js"></script>
<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/engine.js"></script>
<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/util.js"></script>

Nota que estos javascript estn bajo la carpeta /dwr, que es


el servlet que hemos creado prrafos arriba. Adems, hay un
Calculadora.js, que tiene el mismo nombre de nuestra clase
java que hemos creado.
Crearemos la funcin sumar() que es llamada desde el botn
"sumar" de nuestro formulario:
function sumar(){
var valor1=dwr.util.getValue("valor1");
var valor2=dwr.util.getValue("valor2");
Calculadora.sumar(valor1,valor2,mostrarSuma);
}

34

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


En las dos primeras lneas estamos obteniendo los valores de
los tag "valor1" y "valor2". Este nombre es el nombrado en
los atributos id de los input:text. Por ello es importante que
los ID identifiquen a un nico tag en toda la pgina.

La tercera linea llama al objeto Calculadora. Este objeto es el


que DWR cre como contraparte a nuestra clase java
Calculadora.

Nota que llama al mtodo sumar() y recibe tres parmetros.


Los dos primeros son los mismos parmetros que hemos
declarado en nuestra clase java Calculadora. Pero el tercer
parmetro, que se llama mostrarSuma, es el nombre de una
funcin en javascript que se encargar de recibir y manejar el
resultado que devuelto por el mtodo sumar() de java. As es
la convencin de DWR. Notar que se le est pasando solo el
nombre, sin parntesis.

La funcin javascript mostrarSuma() ser la siguiente:

function mostrarSuma(resultado){
dwr.util.setValue("suma",resultado);
}

35

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Vemos que el resultado devuelto por el mtodo de java
sumar() es el parmetro de esta funcin javascript. Tomamos
el valor y lo mostramos en el tag que tiene nombre "suma"
(que es un <div>).

El index.jsp completo es el siguiente:

<%@page contentType="text/html" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8">
<title>JSP Page</title>
<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/interface/Calculadora.js"></script>
<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/engine.js"></script>
<script type="text/javascript"
src="<%=pageContext.getServletContext().getContextPath()
%>/dwr/util.js"></script>
<script type="text/javascript">
function sumar(){
var valor1=dwr.util.getValue("valor1");
var valor2=dwr.util.getValue("valor2");
Calculadora.sumar(valor1,valor2,mostrarSuma);
}
function mostrarSuma(resultado){
dwr.util.setValue("suma",resultado);
}
</script>
</head>

36

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


<body>
<h2>Calculadora</h2>
<form action="">
Valor 1: <input type="text" name="valor1" id="valor1"/><br/>
Valor 2: <input type="text" name="valor2" id="valor2"/><br/>
<input type="button" value="Sumar" onclick="sumar()"/><br/>
Resultado:<div id="suma"></div>
</form>
</body>
</html>

Lo corremos y probamos:

Magia!

37

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Con base de datos
A esta altura vers la simpleza del DWR, y que una aplicacin
con base de datos no sera de lo ms difcil. Haramos una
clase que accede la base de datos y lo muestre en la web.
Pero cmo lo mostramos en una tabla?. Aqu mostraremos el
ejemplo:

Crearemos una clase llamada PersonasService y lo


guardaremos en el paquete logica. Esta clase tendr la
anotacin@RemoteProxy pero con un parmetro que
cambiar el nombre del objeto javascript. Es decir, no se
llamarPersonasService en javascript, sino, se llamar
solamente Personas.

package logica;
import org.directwebremoting.annotations.RemoteProxy;
@RemoteProxy(name = "Personas")
public class PersonasService {
}

38

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Ahora, crearemos un mtodo llamado getLista() que
devolver una lista de objetos Persona que tendr los
registros de la base de datos. Para ello, primero crearemos la
clase beans.Persona.

package beans;
import java.util.Date;

public class Persona {

private int id;


private String nombre;
private String titulo;
private boolean viajeroFrecuente;
private Date ultimaActualizacion;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}

39

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public Date getUltimaActualizacion() {
return ultimaActualizacion;
}
public void setUltimaActualizacion(Date ultimaActualizacion) {
this.ultimaActualizacion = ultimaActualizacion;
}
public boolean isViajeroFrecuente() {
return viajeroFrecuente;
}
public void setViajeroFrecuente(boolean viajeroFrecuente) {
this.viajeroFrecuente = viajeroFrecuente;
}
}

Por alguna razn, los beans con anotaciones no son


convertidos por DWR a objetos JavaScript. Al menos con esta
versin. He seguido la documentacin que indica cmo usar
un bean con @DataTransferObject y nada. Si alguien lo puede
lograr, lo agradecer un montn.

Pero para poder enviar beans en DWR, crearemos un archivo


llamado dwr.xml y lo guardamos dentro del directorio WEBINF (en la misma ubicacin del archivo web.xml). En ese
archivo colocaremos lo siguiente:

40

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://directwebremoting.org/schema/dwr20.dtd">
<dwr>
<allow>
<convert converter="bean" match="beans.Persona">
</convert>
</allow>
</dwr>

Ahora, volvemos a la clase PersonasService. Hacemos clic


derecho sobre el fondo del cdigo fuente, y seleccionamos
Enterprise Resource > Use Database.

Hacemos clic en el botn "Add"

41

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

Pondremos como nombre de la referencia, el valor de


travelDS. Adems, hacemos clic en el botn "Add" de "Project
Data sources", escribimos el nombre del JNDI jdbc/travel y
seleccionamos de la lista el URL del JDBC referido a la base de
datos travel.

Clic en OK

Clic en OK

42

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)

Clic en OK

Veremos que NetBeans nos ha creado un mtodo llamado


getTravelDS()

private DataSource getTravelDS() throws NamingException {


Context c = new InitialContext();
return (DataSource) c.lookup("java:comp/env/travelDS");
}

Pues ya con esto, podemos hacer nuestro manejo a la base


de datos.

Ahora s, crearemos el mtodo getLista():

43

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


@RemoteMethod
public List<Persona> getLista() {
try {
DataSource ds = getTravelDS();
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM person");
List<Persona> lista = new ArrayList<Persona>();
while (rs.next()) {
Persona p = new Persona();
p.setId(rs.getInt("PERSONID"));
p.setNombre(rs.getString("NAME"));
p.setTitulo(rs.getString("JOBTITLE"));
p.setViajeroFrecuente(rs.getBoolean("FREQUENTFLYER"));
p.setUltimaActualizacion(rs.getDate("LASTUPDATED"));
lista.add(p);
}
return lista;
} catch (SQLException ex) {
Logger.getLogger(PersonasService.class.getName()).log(Level.SEVERE
, null, ex);
} catch (NamingException ex) {
Logger.getLogger(PersonasService.class.getName()).log(Level.SEVERE
, null, ex);
}
return null;
}

La interfaz web
Ahora, para terminar, lo ms importante de una aplicacin: la
interfaz web.
Crearemos una tabla donde se colocarn los datos de los
registros obtenidos de la base de datos. Esta tabla ser as:

44

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


<input type="button" onclick="mostrarPersonas()"
value="Mostrar personas"/>
<input type="button" onclick="limpiarCuadro()"
value="Limpiar cuadro"/>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Cargo</th>
</tr>
</thead>
<tbody id="personas">
<tr id="pattern" style="display:none">
<td id="id"></td>
<td id="nombre"></td>
<td id="titulo"></td>
</tr>
</tbody>
</table>

Nota
que
hay
una
fila
que
est
invisible
(style="display:none"). Esta ser nuestra plantilla llamada
"pattern". Cuando llenemos los datos de la base de datos, lo
que haremos ser duplicar esta fila por cada registro.

Vemos tambin que hay un botn que se llama "Mostrar


Personas"
que
llama
a
la
funcin
JavaScript
mostrarPersonas(), que es la est aqu:

45

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


function mostrarPersonas(){
Personas.getLista(listarPersonas);
}

Es decir, estamos llamando al mtodo getLista() del objeto


JavaScript Personas que el DWR cre. El mtodo
correspondiente en java no tiene parmetros, pero aqu
estamos pasndole un argumento. Este argumento es el
nombre de la funcin JavaScript que procesar el resultado
devuelto por el mtodo java. Y la funcin listarPersonas() est
aqu:

function listarPersonas(data){
limpiarCuadro();
for(var i=0;i<data.length;i++){
fila=data[i];
var $id=fila.id;
dwr.util.cloneNode("pattern",{idSuffix:$id});
dwr.util.setValue("id"+$id,fila.id);
dwr.util.setValue("nombre"+$id,fila.nombre);
dwr.util.setValue("titulo"+$id,fila.titulo);
$("pattern"+$id).style.display="";
}
}

Lo que primero hace es limpiar el cuadro (luego presento la


funcin que limpia la tabla). Vemos tambin que est
recibiendo un parmetro. Como vimos en el ejemplo anterior,
este es el resultado que est devolviendo el objeto java.
Lo que hacemos es recorrer todas filas de la lista, tomamos
una fila y obtenemos el ID de ese objeto.

46

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


Este ID nos permitir identificar a esa nica fila, porque
sabemos que cada ID de la tabla es nica.
Luego clonamos la plantilla:
dwr.util.cloneNode("pattern",{idSuffix:$id});
Al clonarla, hacemos que el ID de la fila creada tenga como
subfijo el ID del objeto java. Es decir, al clonar una fila, toda
la fila queda idntica al patrn, incluyendo los nombres de los
ID, que segn el patrn es "pattern". Si el primero registro de
la tabla tiene el valor "1" en el campo "ID", cuando clone la
fila pondr como nombre del ID "pattern" y terminar con el
valor "1", o sea, se llamar finalmente "pattern1", y las celdas
"nombre1", "titulo1" . Para la segunda fila ser "pattern2" y
las celdas "nombre2","titulo2"... y as sucesivamente.
Ya clonamos la fila pattern, ahora colocaremos los valores a
cada celda. Como ya tenemos el ID unico de cada celda,
simplemente colocaremos el valor en ellas
dwr.util.setValue("id"+$id,fila.id);
dwr.util.setValue("nombre"+$id,fila.nombre);
dwr.util.setValue("titulo"+$id,fila.titulo);

Pero como tambin se clon el estilo - que indica que debe


estar oculto - le indicamos que se muestre.
$("pattern"+$id).style.display="";

...y listo.
A continuacin las funciones que borran el contenido de la
tabla:

47

Gua con Ejemplos

CURSO DE DIRECT WEB REMOTING (DWR)


function limpiarCuadro(){
dwr.util.removeAllRows("personas",{filter:filtroBorrado});
}
function filtroBorrado(tr){
return (tr.id!="pattern");
}

Existe la funcin filtroBorrado() para evitar que la fila


"pattern" sea borrada. Si no, cmo hacemos la clonacin?
Y el resultado es el ya esperado...

Para terminar...
Revisa la documentacin de DWR, ah encontrars muchas
cosas muy interesantes.

48

Gua con Ejemplos

También podría gustarte