Geek & Roll - Blog Archive » Programando con Google Web Toolkit (Parte #3)

Programando con Google Web Toolkit (Parte #3)

Cesar March 2nd, 2007 programacion 16 comentarios

Introducción

Esta es la parte 3 de n artículos sobre programación con Google Web Toolkit. La primera parte se enfocó en compilar nuestro primer programa, un hola mundo, para familiarizarnos con este toolkit. La segunda parte fue un poco más práctica y se mostró una aplicación de ejemplo que básicamente mostraba como es el paradigma de la interfaz gráfica con GWT. Para esta tercera entrega comenzaremos a utilizar un IDE que nos ayudará a la hora de la programación y depuración, además de hacer nuestras primeras llamadas AJAX que, al final de cuentas, es por lo que muchos exploran GWT.

Googlipse es tu mejor amigo

Ya dijimos que vamos a utilizar un IDE, pero no solo cualquier IDE sino EL IDE. Me refiero a Eclipse. Este IDE es una especie de meta-herramienta, un IDE para todo y nada en particular. Se puede extender por medio de plugins y soportar una multitud de lenguajes y herramientas externas. Si a Eclipse le agregamos el plugin Googlipse, tenemos un IDE para Java capaz de generar y mantener proyectos GWT, lanzarlos y depurarlos entre otras cosas.

La instalación de Googlipse requiere de tener el Web Tools Plataform (además del propio Eclipse), el cual provee APIs para desarrollo de aplicaciones basadas en Web. Para no complicar mucho las cosas, yo recomiendo que bajen Eclipse ya integrado con Web Tools Plataform de su página web. Solo necesitan descomprimir el archivo descargado a un directorio y ejecutar Eclipse de ahí. Al tiempo de la escritura de este artículo la última versión de Eclipse es la 3.2. Si quieren verificar que Web Tools Plataform se encuentra correctamente instalado pueden ver en el menu Help | About Eclipse SDK About presionar el botón “Plugin Details” como se muestra en la imagen.

Con WTP en su lugar, solo hay que descargar ahora el propio Googlipse de su web http://www.googlipse.com. En este mismo sitio describen como instalar Googlipse (es muy sencillo):

  1. Descomprimir el archivo bajado, y copiar el archivo com.googlipse.gwt*.jar al directorio instalacion_eclipse/plugins. Claro que hay que sustituir instalacion_eclipse por el directorio donde instalaron eclipse con Web Tools Plataform
  2. Abrir Eclipse. Seleccionar Window | Preferencias | Googlipse y llenar la caja de texto donde dice GWT home al directorio donde tienen instalado Google Web Toolkit
  3. Listo

De la misma manera que verificamos si se encontraba instalado WTP, se puede verificar que Googlipse se instaló correctamente. Solo hay que buscar el nombre Googlipse en la ventana de plugins instalados. Para crear un nuevo proyecto de GWT para Eclipse ya no es necesario seguir utilizando la aplicación applicationCreator como antes, ahora tan solo nos vamos a File | New | Project y bajo el nodo “Web” seleccionamos “Dynamic Web Project”. Nos aparecerá una ventana como la que se muestra a continuación.

Ventana de proyecto

Hay que asegurarse de seleccionar de la lista Configurations, la opción “Default Googlipse Project”. A menos de que tengan requerimientos especiales, en este momento pueden presionar Finish después de llenar el nombre del proyecto. No es el objetivo de este artículo explicar todo el funcionamiento de Eclipse, sino solo lo referente a su uso con GWT, así que está de más decir que una vez que se genera toda la jerarquía de directorios del proyecto, damos click derecho sobre Java Resources: src y creamos un nuevo paquete para administrar nuestros archivos fuente.

Navegador de proyecto

Con esto podemos comenzar a programar con GWT y Eclipse. Para agregar un nuevo módulo damos click derecho sobre el paquete, New | Other | Googlipse | Module. Llenamos los datos necesarios y presionamos Finish. Podemos notar como Googlipse se encarga de crear el paquete client en donde genera la nueva clase Java. De la misma manera podemos seguir agregando nuevos módulos. Para ejecutar una aplicación GWT desde Eclipse, seleccionamos el módulo (archivo .gwt.xml) damos click derecho y seleccionamos Run As | GWT Hosted Mode Application, lo mismo para depurar solo que en vez de Run As, seleccionamos Debug As. Para más información podemos consultar la página de Googlipse.

Con nuestro poderoso IDE funcionando, pasemos a lo realmente AJAX del asunto.

Remoting o llamadas clásicas, he ahí el dilema

El título de esta sección no es nada más para hacerme el gracioso, realmente es un dilema. Para propósitos de aprender a programar con GWT es bueno que se aprendan las dos aproximaciones, sin embargo, normalmente solo se utilizará una de las dos al estar programando una aplicación “del mundo real”.

La primera aproximación es la preferida (por así decirlo) para programar con GWT. Digo que es la preferida ya que el código que corre en el servidor se programa también en Java. Remote Procedure Call (RPC) es prácticamente un servlet que se comunica con nuestra aplicación cliente, además de una clase proxy que nos permite definir que pasa si la llamada remota es completada correctamente o si sucede algún error. Esto es a muy grandes rasgos, más adelante la explicación detallada.

La segunda aproximación es hacer llamadas remotas a programas script corriendo en el servidor. Esta manera de ejecutar código del servidor es típica cuando ya se tiene una aplicación web (digamos en PHP) y se le quiere agregrar algo de magia AJAX, o tal vez se tenga una librería en otro lenguaje script y no se quiere reprogramarlo en servlets, o tal vez simple y sencillamente no se quiere trabajar con Java en el lado del servidor. Aunque GWT incluye una clase llamada HTTPRequest para hacer esta tarea “simple”, el problema es que normalmente las llamadas interdominios (de un dominio a otro) por medio del objeto XMLHTTPRequest (que se utiliza por la clase HTTPRequest) se bloquean en el navegador por motivos de seguridad lo que resulta en un error al querer hacer la llamada por medio de HTTPRequest.

Para no hacer el cuento muy largo, si se puede lograr hacer las llamadas remotas por medio de HTTPRequest a un servidor en otro dominio, pero se necesitan hacer algunos ajustes antes. Existen varias formas, aquí solamente se explorarán dos: utilizar un filtro de tomcat para redirigir las peticiones y modificar los permisos de Firefox para permitir las llamadas interdominio. Para la utilización de un filtro de tomcat pueden leer el artículo “Haciendo llamadas interdominio con GWT” en donde se explica a detalle el proceso.

Remote Procedure Calls

El uso de RPC para las llamadas al servidor tiene varias ventajas. Primero, el hecho de que todo se programe en Java le proporciona cierta claridad y coherencia al código, además de poder programar todo en el mismo IDE y en el mismo lenguaje. Segundo, RPC nos permite intercambiar objetos entre el servidor y el cliente. Esto a diferencia de HTTPRequest con el que podemos intercambiar solamente datos de texto (XML, JSON o lo que sea) que se pueden o no convertir a un objeto en el cliente, pero eso agrega otro paso más que es innecesario con RPC. Y tercero y muy importante, con RPC se puede depurar el código que se encuentra del lado del servidor desde el mismo IDE… ¡algo extremadamente útil!

Sin embargo, RPC también tiene sus desventajas. Si nunca has programado con RPC posiblemente lo encuentres un poco menos intuitivo que hacer lo mismo con HTTPRequest. Además, RPC requiere que tu código del servidor se encuentre corriendo dentro de un contenedor J2EE (recuerda, ¡son servlets!) y no siempre tenemos uno a la mano. Normalmente los proveedores de hosting incluyen en sus planes php pero no un contenedor J2EE a menos que este servicio sea específicamente contratado, lo que puede complicarnos la vida al momento de querer instalar la aplicación en un servidor fuera de nuestra computadora.

Con las características básicas a un lado, podemos comenzar a hablar en código. La siguiente es una lista de lo que se necesita desarrollar para utilizar RPC:

  • Una interfaz que defina el servicio remoto, en el lado del cliente. Esta interfaz deberá extender la interfaz RemoteService. En pocas palabras esta interfaz define los métodos disponibles en el servidor.
  • El propio servicio remoto. Este servicio es un servlet que se encuentra en el lado del servidor y debe extender la clase RemoteServiceServlet. Además, esta clase debe extender la interfaz definida en el cliente.
  • Configurar el servlet dentro del contenedor.
  • Agregar la clase Async en el cliente. Esta clase se llama igual a la interfaz definida en el cliente solo que se le agrega Async al final del nombre. Además debe implementar todos los métodos de la misma interfaz agregándole el parámetro callback del tipo AsyncCallback. Esta será la clase que usaremos al final de cuentas para comunicarnos con el servidor como si de una clase del cliente se tratara.

Como dijo Jack el Destripador, vamos por partes. Primero vamos a definir que queremos hacer en el servidor para después llamarlo por medio de RPC y HTTPRequest, ver las diferencias entre las dos, etc. Espero que recuerden la pequeña aplicación de demostración que hicimos en la parte 2 porque tomaremos esa de base para este ejemplo.

Lo que vamos a hacer es eliminar la deficiencia de tener el nombre de usuario y el password definidos en el código. En esta aplicación le enviaremos al servidor nuestro nombre de usuario y el password y el servidor nos deberá de contestar (normalmente consultando una base de datos) con un valor booleano si los datos fueron correctos o no. También vamos a enviar al servidor los datos capturados por el usuario (encapsulados en un objeto del tipo Usuario) y esperar a que el servidor nos regrese otro objeto usuario con los datos que se le enviaron (para confirmar que llegaron correctamente). Normalmente el servidor haría uso de una base de datos, EJBs o cualquier otra tecnología que aquí evitamos para no hacer más complicado el ejemplo.

Podemos comenzar a programar todo a mano: mantener la clase Async en sincronía con la interfaz del cliente, configurar el servlet… pero para eso ya instalamos Googlipse y aprovechando sus bondades lo vamos a hacer desde el IDE. Primero hay que agregar un nuevo servicio remoto. Click derecho en el paquete del cliente (en mi caso com.geekandroll.jolette.client) New | Other | Googlipse | Remote Service. Aparece la siguiente imagen.

RPC

Hay que llenar los detalles, el nombre del servicio remoto (este será el nombre de la interfaz del servicio en el cliente) y la URI del servicio (utilizada para localizar al servicio remoto en el servidor). En el momento que damos click en Finish se generan varios archivos: la interfaz del servicio (ClientManagement.java) y la clase que necesitamos para hacer uso del servicio remoto (ClientManagementAsync.java) del lado del cliente (com.geekandroll.jolette.client). Además Googlipse nos acaba de crear el paquete com.geekandroll.jolette.server el cual contiene la implementación del servicio remoto (o sea, el que hace el trabajo del lado del servidor). No solo eso, sino que cualquier cambio en la interfaz del cliente (ClientManagement) al ser guardado el archivo Googlipse automágicamente actualiza la clase Async así nosotros nos olvidamos de esa tediosa tarea. Googlipse también se encarga de generar una clase estática llamada “Util” dentro de la interfaz del cliente, más adelante veremos para que hace esto (bastante útil).

En este momento lo más probable es que Eclipse se encuentre marcando un error en la implementación del servicio remoto, y eso es porque como implementa la interfaz del cliente, debe proveer los métodos marcados por dicha interfaz. Así que manos a la obra. Mi interfaz ClientManager declara los siguientes métodos:


Boolean isLoginCorrect(String username, String pass);
Usuario saveUserDetails(Usuario u);

Así que estos dos métodos son los que tenemos que crear en la implementación del servicio remoto. La clase ClientManagementImpl.java se muestra a continuación:


package com.geekandroll.jolette.server;

import com.geekandroll.jolette.client.ClientManagement;
import com.geekandroll.jolette.client.Usuario;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class ClientManagementImpl extends RemoteServiceServlet implements ClientManagement {
/*¿¿ SuperCryptoMegaFunction ?? */
public Boolean isLoginCorrect(String user, String pass){
user = user.toLowerCase();
char[] tempPass = new char[user.toCharArray().length];

for(int i=0;i tempPass[i] = user.toCharArray()[tempPass.length - 1 - i];

String correctPass = String.valueOf(tempPass);
if(pass.equals(correctPass))
return new Boolean(true);
else
return new Boolean(false);
}

public Usuario saveUserDetails(Usuario u){
/*En este punto, se puede consultar una base de datos,
* hacer uso de un EJB, o cualquier cosa que se pueda
* hacer desde un servlet. Hay que usar la imaginación
* para hacer de este ejemplo algo representativo.*/
return u;
}
}

Solamente viendo el nombre de los métodos vemos de que se tratan. isLoginCorrect() recibe el nombre de usuario y el password y verifica si son correctos. En caso de ser correctos regresa un objeto Boolean con valor true, o con valor false en caso de ser incorrectos. ¿Como hace para verificar si son correctos o incorrectos? no voy a explicar este trozo de código a propósito, para que pongan a trabajar la neurona. saveUserDetails() recibe un objeto Usuario y solamente regresa el mismo objeto. El propósito de esto es ilustrar como se le pueden pasar POJOs (Plain Old Java Objects) a un servicio remoto utilizando RPCs y trabajar con estos objetos en el servidor como si estuviesen en el cliente. ¡Muy Bonito!

Una nota rápida: como vamos a enviar el objeto Usuario al servidor, es necesario que este implemente la interfaz IsSerializable que viene dentro del paquete com.google.gwt.user.client.rpc. Para esto solamente modificamos la clase Usuario original, quedando declarada de la siguiente manera:


package com.geekandroll.jolette.client;

import com.google.gwt.user.client.rpc.IsSerializable;

public class Usuario implements IsSerializable{
private String nombre;
private String email;
private String password;
...

Ahora sí, estamos listos para llamar a nuestro servicio remoto. Lo que queremos lograr es que cuando el usuario de click en el botón de login se llame al servicio remoto, se verifiquen los datos y el servidor nos diga si son correctos o no. Recordando un poco la interfaz gráfica de este programa veamos la siguiente descripción del artículo 2:

Pantalla inicial
Al inicio, la aplicación muestra solo un link para conectarse. Al dar click sobre el link, se abre una ventana emergente (popup) para introducir el nombre de usuario y el password.

Popup

Este popup contiene un botón que cuando se presiona, verifica que el nombre de usuario y el password sean correctos. En caso de ser correctos la aplicación cambia para mostrar la interfaz principal.

Dentro

La interfaz principal contiene el StackPanel en el cual podemos ingresar información y dar click sobre el botón dentro de la sección Vista Previa. Al dar click, la información contenida en los campos de texto del StackPanel se reflejan sobre el panel de la derecha.

Entonces hay que modificar el evento del botón. Sea lo que sea que esté haciendo ahora, vamos a sustituirlo por el código para llamar a nuestro servicio remoto. Actualmente el evento para ese botón en particular se ve así (JoletteStart.java):


public void onClick(Widget sender){
if(sender.equals(loginLink)){
/*Acciones de loginLink*/
}else if(sender.equals(loginButton)){
if(user.getText().equals("cesar") && pass.getText().equals("1234")){
popup.hide();
Iterator iterator = RootPanel.get().iterator();
while(iterator.hasNext()){
RootPanel.get().remove((Widget)iterator.next());
}

loginSuccesful();
}
}
}

Vemos que solamente verifica que el nombre de usuario sea "cesar" y el password sea "1234". De ser así se llama a loginSuccesful(). Lo modificaremos para que se vea de la siguiente manera:


public void onClick(Widget sender){
if(sender.equals(loginLink)){
/*Acciones de loginLink*/
}else if(sender.equals(loginButton)){
ClientManagementAsync clientManagement = ClientManagement.Util.getInstance();

AsyncCallback callback = new AsyncCallback(){
public void onSuccess(Object result){
Boolean validUser = (Boolean)result;
if(validUser.booleanValue()){
popup.hide();
loginSuccesful();
}else{
popup.hide();
RootPanel.get().add(new Label("Nombre de usuario y/o password incorrecto"));
}
}

public void onFailure(Throwable caught){
popup.hide();
RootPanel.get().add(new Label("Error al comunicarse con el servidor"));
}
};

clientManagement.isLoginCorrect(user.getText(), pass.getText(), callback);
}
}

Explicaré un poco el código. Primero se crea una instancia de ClientManagementAsync, utilizando el método getInstance() de la clase Util dentro de ClientManagement (recuerden que esta clase la generó automáticamente Googlipse). Por ahora no hay que preocuparse mucho por el funcionamiento de getInstance() solo hay que saber que nos da la instancia de la clase Async con la cual llamaremos a nuestro servicio remoto.

La última linea es la que hace la llamada. Una vez teniendo la instancia de la clase Async, tan solo llamamos al método isLoginCorrect() y le pasamos los parámetros nombre de usuario y password, además de un objeto AsyncCallback que servirá para que se llame el método onSuccess() si la llamada al servicio remoto fue exitosa, o de lo contrario se llame a onFailure(). Precisamente de ahí la necesidad de crear la interfaz Async (y la ventaja de que Googlipse la mantenga en sincronía), ya que es esta la que agrega el requerimiento del objeto AsyncCallback en las llamadas al servidor.

Solo resta explicar el objeto callback. Si vemos la documentación para AsyncCallback, vemos que realmente es una interfaz que todo aquel que llame un servicio remoto debe implementar para poder recibir respuesta del servidor. Obviamente ya vimos que esta interfaz nos dicta la implementación de onSuccess() y onFailure(). En este caso el servidor regresa un objeto como resultado, al cual se le hace cast a Boolean (por eso se utiliza Boolean y no boolean) y se extrae su valor para ver si el usuario y el password son correctos. Todo esto pudo ir en una clase aparte, instanciar un objeto del tipo de esta clase y pasarlo como argumento al método isLoginCorrect, es solo que para propósitos del ejemplo es mejor tenerlo todo en un mismo archivo.

Ahora hay que hacer lo mismo pero para saveUserDetails(), recibir la respuesta del servidor y desplegarla en el panel de salida. Lo que tenemos que hacer es que al dar click sobre el botón para enviar los datos, se construya un objeto Usuario, se envíe al servidor, y lo recibamos de regreso para enviarselo al panel de la derecha. Puede sonar algo reduntante pero solo es para ilustrar como podemos enviar y recibir objetos, no estamos limitados a solo texto o tipos de datos como int, boolean, etc.

El código actual para el evento onClick del botón en MyStackPanel es como se muestra:


public void onClick(Widget sender){
try{
Usuario u = new Usuario();
u.setNombre(txtnombre.getText());
u.setEmail(txtemail.getText());
u.setPassword(txtpass.getText());
u.setCuenta(txtcuenta.getText());

JoletteStart.get().displayOutput(u);
}catch(Exception e){
e.printStackTrace();
}
}

Justo después de llenar el último dato del usuario, vamos a enviar el objeto al servidor:


public void onClick(Widget sender){
try{
Usuario u = new Usuario();
u.setNombre(txtnombre.getText());
u.setEmail(txtemail.getText());
u.setPassword(txtpass.getText());
u.setCuenta(txtcuenta.getText());

ClientManagementAsync clientManagement = ClientManagement.Util.getInstance();

AsyncCallback callback = new AsyncCallback(){
public void onSuccess(Object o){
JoletteStart.get().displayOutput((Usuario)o);
}
public void onFailure(Throwable caught){
JoletteStart.get().displayOutput("Error de comunicación con el servidor");
}
};
clientManagement.saveUserDetails(u, callback);
}catch(Exception e){
e.printStackTrace();
}
}

Fácilmente podríamos modificar el código para enviar cada uno de los datos que componen a un usuario y que el servidor, una vez que los persista en una base de datos, nos regrese un objeto usuario para poder trabajar con él en el cliente. Como vemos, utilizar llamadas RPC es muy sencillo una vez que se tienen todos los elementos involucrados, solamente es cuestión de crear la instancia de la clase Async, llamar al método remoto y proveer un objeto encargado de recibir la respuesta del servidor.

La clase HTTPRequest

La descripción de esta clase en la documentación nos dice que:

Esta clase te permite hacer peticiones HTTP asíncronas al servidor de origen.

Tengo que confesar que al inicio, yo pensaba que esta era la manera de hacer las cosas en GWT. Y como no, acostumbrado a programar JavaScript en... JavaScript, obviamente estaba buscando la alternativa del infame XMLHTTPRequest. Con solo cuatro métodos, la clase HTTPRequest es súper sencilla de utilizar ya sea para peticiones GET o POST. Mi idea era trabajar como lo había hecho hasta la fecha: hacer la petición, recibir un documento XML como respuesta del servidor, parsearlo en el cliente y continuar la ejecución. Se puede trabajar de esa manera sin problemas, además GWT incluye la clase XMLParser que te ayuda a crear documentos XML desde cero o a partir de una cadena (que puede venir del servidor como respuesta) para ser manipulados por el DOM. Así es, GWT también incluye una clase para manipular el DOM.

Hay que tener en cuenta que las mismas restricciones aplican a la clase HTTPRequest que a lo que utiliza para hacer la llamada asíncrona: XMLHTTPRequest. Esto quiere decir que los navegadores típicamente no permitirán hacer llamadas a otro dominio desde el dominio de origen. Otro dominio se entiende por:

  • Una petición que se origina de www.geekandroll.com con destino a www.cesarolea.com
  • Una petición que se origina de localhost con destino a www.geekandroll.com
  • Una petición que se origina de localhost:8888 con destino a localhost:80

En otras palabras, el decir "otro dominio" significa procesos distintos, aún cuando estos se encuentren en la misma computadora. Esto nos deja con la única opción de poder hacer llamadas solamente al servidor desde donde se originó la misma llamada, o sea, si tenemos nuestra aplicación hosteada en un servidor apache en el puerto 80, solamente a ese mismo servidor en ese mismo puerto se pueden hacer las llamadas remotas. Si tenemos nuestra aplicación hosteada en un contenedor tomcat en el puerto 8888 (el caso del modo hosted) solamente podemos hacer llamadas a ese mismo contenedor en ese mismo puerto. ¿Ven el problema? Esto es una limitante de los navegadores, una medida de seguridad y no una deficiencia por parte de GWT.

Aclaración: a partir de este punto en adelante, estoy suponiendo que ya leyeron como hacer llamadas remotas interdominio con GWT. Si no lo han hecho aún, vayan, aquí los espero.

¿Ya? Ok. De la misma manera que con RPC, vamos a modificar el código responsable para hacer las llamadas solo que ahora en vez de utilizar RPC vamos a utilizar HTTPRequest. Veamos el caso del login:


public void onClick(Widget sender){
if(sender.equals(loginLink)){
/*Acciones de loginLink*/
}else if(sender.equals(loginButton)){
if(user.getText().equals("cesar") && pass.getText().equals("1234")){
popup.hide();
Iterator iterator = RootPanel.get().iterator();
while(iterator.hasNext()){
RootPanel.get().remove((Widget)iterator.next());
}

loginSuccesful();
}
}
}

Lo cambiamos para utilizar HTTPRequest:


public void onClick(Widget sender){
if(sender.equals(loginLink)){
/*Acciones de loginLink*/
}else if(sender.equals(loginButton)){
boolean success = HTTPRequest.asyncPost("http://localhost:80/jolette/login.php", "user="+
user.getText()+"&pass="+pass.getText(), new ResponseTextHandler(){
public void onCompletion(String responseText){
if(responseText.equals("ok"))
loginSuccesful();
else
Window.alert(responseText);
}
});
if(success){
Window.alert("Exito");
}else{
Window.alert("Error");
}
}
}

Realmente es muy sencillo, el método HTTPRequest regresa true o false dependiendo si la petición pudo ser completada. En teoría no deberíamos de probar el evento if(success) pero aquí lo hacemos para ser explícitos y confirmar que la llamada fue exitosa. Obviamente vemos que el servidor nos debe regresar la cadena "ok" para representar petición exitosa y continuar con el programa. En vez de ese simple "ok" se podría regresar un documento XML (como cadena) y utilizar XMLParser para parsearlo y manipularlo, pero esa es otra historia (lo dejamos para otro tutorial). El código anterior se puede reescribir de la siguiente manera para hacerlo más compacto:


if(!HTTPRequest.asyncPost("http://localhost:80/jolette/login.php",
"user="+user.getText()+"&pass="+pass.getText(),
new ResponseTextHandler(){
public void onCompletion(String responseText){
Window.alert(responseText);
}
}))Window.alert("Error");

Para el ojo poco entrenado puede parecer algo críptico, pero una vez que te acostumbras a esta representación es más compacto y hasta hace más sentido. Si la petición falla muy probablemente sea por las restricciones interdominio. Y realmente no hay mucho más que decir de HTTPRequest. Fácilmente se ve la flexibilidad de RPC contra HTTPRequest, pero con los dos es posible hacer las peticiones asíncronas que construyen lo que hoy se conoce como AJAX.

Conclusión

En esta tercera entrega se detalló como crear un ambiente de desarrollo para GWT utilizando Eclipse. Entre las ventajas que esto nos da es poder contar con un ambiente gráfico consistente entre distintas plataformas, que nos permite crear proyectos, compilarlos y depurarlos desde la misma herramienta, además de crearnos y mantenernos módulos y servicios remotos que también se pueden depurar aún cuando corren en el lado del servidor.

Vimos también como crear estos servicios remotos, las ventajas y desventajas que presenta el trabajar a la manera GWT (RPC) o con HTTPRequest. Las dos aproximaciones son factibles en distintos ambientes y cual seleccionen debe depender de la tarea en mano.

¡Y lo que falta!

¡Phew! fue más largo de lo que esperaba. Aún así hay más material de GWT que compartir. Está por supuesto el tema de la integración de GWT con Spring (que ya lo sugerió alguien en mi blog personal. Además el uso de widgets de terceros con GWT, etc. Lo que no quiero es que esta serie de artículos se conviertan más en "programación con Java" que enfocarse a GWT por lo que el tema del uso de EJBs por ejemplo tendrá que quedar por fuera.

¿Y entonces que falta? la verdad no lo se. Se aceptan sugerencias (usen la caja de comentarios), comentarios, contribuciones, críticas y demás (menos SPAM). Si esta tercera parte tuvo que esperar algún tiempo muy probablemente la cuarta parte tarde un poco más. Por mientras, muy probablemente termine otros proyectos que tengo en mente y pueda compartir algo más de código con todos.

¡Hasta la próxima!

16 Comentarios

Cristian

September 17th, 2007

Excelente material!

Saludos!

Antonio

October 5th, 2007

Muy buena tú ayuda sin embargo me falta muho por recorrer… quisiere ver si estas en condiciones de ayudar a un principiante en Java….

Cesar

October 9th, 2007

Que tal Antonio. Claro que puedo ayudar a un principiante en Java, aunque la audiencia para la que va dirigida este tutorial no es precisamente para novatos en Java.

Te recomiendo que leas mi pequeña introducción a Java y si aún tienes dudas puedes escribirme un correo con tus comentarios.

Saludos!

supreme

November 11th, 2007

falta el paquete para descargar :P

Y además las wtp ya no son las mismas, googlipse ya no se llama así, y no viene ningún archivo para ingresar a la carpeta de plugins (o features) no recuerdo, por lo que, a pesar de que he seguido al pie de la letra tu tutorial, no he obtenido los resultados deseados. Ahora procedo a bajar el paquete completo con eclipse y las demás cosas.

Es que en internet, unos dias son mucho tiempo. :/

supreme

November 11th, 2007

luego de descargar wtp-all-in-one, todo ha ido perfecto!

GoldenFox

November 12th, 2007

y donde esta la parte #2??

Cesar

November 12th, 2007

@supreme: Que bueno que pudiste resolver todos tus problemas anteriores. Tienes razón Googlipse ya no se llama así, pero este post ya tiene bastante tiempo. La instalación de WTP puede ser algo complicada y si, es más sencillo bajar el paquete completo pero esto a veces no es viable (porque tienes otros plugins ya configurados, etc).

@GoldenFox: La parte 1 y 2 las puedes consultar en mi sitio anterior. Parte 1, Parte 2.

Mary

May 2nd, 2008

Hola:

Yo apenas estoy iniciando en la programación con GWT, de hecho con ayuda de algunos tutoriales estoy siguiendo algunos ejemplos para crear algunas aplicaciones. Ahora en lo que me estoy atorando es en RPC; trato de crear una aplicación que muestre un mensaje cada determinado tiempo, el mensaje cambia, tal vez conozcas ese ejemplo se llama “RandomQuote”, bien, el punto es que no sé qué import podría faltarme, porque en el archivo xxxServiceAsync, por llamarlo así, me desconoce el parámetro AsyncCallback, y pues no sé qué pasa, si tomé la precaución de incluir el import “com.google.gwt.user.client.rpc.AsyncCallback;”, en realidad creo que me haría mucho bien ver un ejemplo con RPC completo, todos los archivos y cons us import correspondientes, ¿qué me dices sobre todo esto?

Marcos

July 6th, 2008

Muy buen artículo, muchas gracias.

¡Y una lástima no tener acceso a los anteriores! Los links de arriba están rotos.

María

November 4th, 2008

Hola
Quiero hacer algo parecido a la parte en la que se envía el objeto Usuario al servidor, lo que me interesa es saber dequé manera puedo guardar esos datos en una tabla llamada Usuario la verdad es que nosé como hacerlo, creo que está la instrucción insert pero nosé como pasarle alobjeto ya lleno como parámetro, agradecería ucho su ayuda, soy un poco nueva en esto de GWT.
Gracias
Maria

Berta

December 16th, 2008

Hola Cesar!

Los link que ha colgado sobre el la 1ª y la 2ª parte del tutorial estan rotos. Podrias volver a colgarlos.

Gracias.

Cesar

December 16th, 2008

@Berta: que tal! Los links sobre la parte 1 y 2 apuntan a mi antiguo blog personal, que en efecto ya no existe :(

Tendre que desempolvar el respaldo y ponerlos aqui para que los puedas consultar.

Jorge

April 21st, 2009

Buenas,
Una pregunta nada mas. Hay alguna manera de convertir aplicaciones java a aplicaciones web con GWT directamente, es decir, sin tener que usar eclipse.
Gracias

Cesar

April 21st, 2009

Claro, GWT no depende de Eclipse de ninguna manera. Puedes compilar tu aplicacion GWT con los scripts que vienen con la distribucion de GWT.

Jorge

April 24th, 2009

Buenas,
Me podrías explicar o mandar un enlace de como convertir una aplicación swing a web mediante GWT. Lo de crear nuevas aplicaciones con GWT ya lo tengo claro como se hace, pero lo de la conversión no mucho. He probado con el plugin de eclipse GWTDesigner y funciona pero a mi me gustaría saber como hacer la conversión directamente desde GWT.
Gracias de antemano

Cesar

April 24th, 2009

Creo que malentendi tu pregunta anterior. No es posible “convertir” una aplicacion Swing a GWT directamente. No es el objetivo de GWT.

Haz un comentario:

Es necesario que dejes tu nombre y correo electrónico (no se publicarán).

Si dejas un comentario anónimo, con insultos o ajeno al tema, iremos hasta tu casa y le diremos a tu mamá la cantidad de porno que hay en tu computadora. Si, lo sabemos.