Operando datos contra el servidor utilizando GWT RPC

Tecnología
- Entorno de desarrollo Eclipse Helios:
- GAE y GWT:

Para realizar esta actividad es necesario introducir algunos conceptos propios de la tecnología que estamos utilizando. Para este caso seguramente les viene en mente que al realizar una solicitud de datos al servidor, lo tenemos que realizar de forma síncrona, sin bien esto es muy variable y dependiendo del lector y su experiencia pueden interpretar que está demás el comentario. Les comento que al hacer uso de GWT, el desarrollador está obligado a utilizar un mecanismo de comunicación asincrónico, por este motivo vamos a utilizar una serie de pasos que les serán de gran utilidad al incorporar desarrollo sobre GWT y GAE.

Introducción

Para esta actividad tenemos que tener en cuenta 4 pasos fundamentales:
1.    Crear el servicio de solicitud de préstamo
2.    Implementar el mecanismo RPC sobre GWT del servicio de préstamo
3.    Crear la interfaz asincrónica
4.    Invocar el servicio de solicitud de préstamo.

La idea del requerimiento a resolver para nuestra actividad es generar un servicio que pueda responder a la solicitud de aprobar o denegar un préstamo. Esta implementación está claramente simulada ya que el objetivo es, comprender como utilizar el mecanismo RPC que propone GWT.
En primer lugar vamos a analizar la anatomía de GWT RPC.

Fig. 1 Anatomía de GWT RPC
En la Fig. 1 se muestra la anatomía de GWT RPC, podemos visualizar en anaranjado los elementos importados desde el framework, en celeste los elementos que generaremos para la implementación y en verde la llamada al proxy desde el entrypoint para poner en funcionamiento el mecanismo.

Crear el servicio de solicitud de préstamo (cliente)

Para este primer segmento de actividad  vamos a situarnos en el paquete “cliente” del modelo que propone GWT. Generamos en este momento la interfaz del servicio de préstamo.
Fig.2 - Implementación en Eclipse de “solicitudService.java”.

package ar.com.comunidadxcloud.nbortolotti.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@RemoteServiceRelativePath("sol")
public interface solicitudService extends RemoteService
{
            public Boolean solicitud(String email, String nombre);
}


Code 1 - Interfaz del servicio de préstamo
La Fig.2 muestra la implementación de la interface del servicio de préstamos en el cliente. El Code 1 expone el código fuente detallado utilizado en “solicitudService.java”, como podemos observar opté por segmentarlo en 3 filas que muestra:
     Fila 1: Paquete en que se encuentra el código fuente referenciado.
     Fila 2: Importaciones de librerías necesarias para la implementación del código fuente.
     Fila 3: interface que permitirá implementar el servicio de solicitud sobre el mecanismo RPC de GWT, para remarcar tengo que exponerles la herencia de “RemoteService” clase que proviene de las librerías rpc de Google GWT.
                Es de vital importancia analizar el atributo @RemoteServiceRelativePath("sol") ,           este se vincula directamente con el “url-pattern” del “servlet-mapping”, establecidos en el archivo “web.xml”.

Implementar el mecanismo RPC sobre GWT del servicio de préstamo (servidor)

Ahora vamos a generar el mecanismo de implementación del servicio. Esto está basado en un Java Servlet. Vamos a heredar de “RemoteServiceServlet” e implementar el servicio de solicitud.

 Fig.3 - Implementación en Eclipse del servicio “solicitudServiceImpl.java”.
package ar.com.comunidadxcloud.nbortolotti.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import  ar.com.comunidadxcloud.nbortolotti.client.solicitudService;
import ar.com.comunidadxcloud.nbortolotti.shared.userDTO;
@SuppressWarnings("serial")
public class solicitudServiceImpl extends RemoteServiceServlet implements solicitudService 
{
            public Boolean solicitud(String email, String nombre)
            {
                        //Genero un objeto simulando una búsqueda
                        userDTO usuario = new userDTO(email, nombre, 2);
                       
                       
                        if(usuario.getCodigoImportancia()== 1)
                        {
                                   return Boolean.TRUE;
                        }
                        else
                        {
                                   return Boolean.FALSE;
                        }                                 
            }
}
Code 2 - Implementación del servicio “solicitudService”
La Fig.3 muestra la implementación en Eclipse de servicio de solicitudes. El Code 2 expone el detalle de implementación, nuevamente está segmentado en 3 filas, analicemos cada una de las mismas.
     Fila 1: Paquete en que se encuentra el código fuente referenciado, como pueden observar su ubicación es el servidor.
     Fila 2: Dentro de las librerías referenciadas se encuentra la más importante en cuanto a la tecnología utilizada “RemoteServiceServlet” desde la cual vamos a heredar el comportamiento y utilizaremos el paquete cliente para implementar la interfaz que creamos en el paso anterior “solicitudService”.
     Fila 3: en esta fila se encuentra la implementación simulada de un método de aprobación o recazo de solicitudes de préstamo. Podemos remarcar la herencia desde “RemoteServiceServlet” y la implementación de la interface “solicitudService”. Luego se crea un objeto a manera de similar datos desde un entorno de datos y finalmente se muestra una estructura que determinar el verdadero o falso de la implementación.

Antes de pasar el siguiente paso es necesario que configuremos el archivo “web.xml”, donde se declaran los servlet en GWT.
La Fig. 4 expone esta configuración en Eclipse donde se debe prestar especial atención a sus partes constitutivas.


Fig.4 - Configuración del servlet en “web.xml”
 
 
 
 …. 
 
    solicitudServlet
    ar.com.comunidadxcloud.nbortolotti.server.solicitudServiceImpl
   
 
 
  ….  
   
     solicitudServlet
     /siscti_cloud_demotracion/sol
   
  .... 
Code 3 - Detalle de la configuración del servlet en GWT.
El code 3, muestra la declaración del servlet y luego el mapeo del servlet, dos actividades importantes para la configuración del servicio en GWT.

Crear la interfaz asincrónica (cliente)

Finalmente antes de generar la llamada al servicio creado vamos a generar la interface asincrónica ubicada en el paquete cliente.


Fig.5 - Implementación de la Interface asincrónica en Eclipse.
La Fig. 5 muestra la implementación en Eclipse de la interface asincrónica, que como podemos observar se encuentra como complemento del servicio en el paquete cliente.
package ar.com.comunidadxcloud.nbortolotti.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface solicitudServiceAsync
{
            void solicitud(String email, String nombre, AsyncCallback callback); 
}
Code 4 - Detalle de la implementación de la interface “solicitudServiceAsync”
El code 4, muestra el detalle de implementación segmentando nuevamente en filas el código fuente.
     Fila 1: Paquete en que se encuentra el código fuente referenciado, como pueden observar su ubicación es el cliente.
     Fila 2: Referencias a librerías en este caso hacemos uso de “AsyncCallback” para el mecanismo asincrónico.
     Fila 3: La declaración de la interface asincrónica con su firma correspondiente.

Invocar el servicio de solicitud de préstamo (cliente).

Con este paso, completamos la implementación de nuestro servicio, vamos a invocar desde el “EntryPoint” del aplicativo concretamente en el evento  “onModuleLoad” la llamada al servicio.
La idea es que permita ingresar un e-mail y un nombre de usuario, con esto ir a buscar si este usuario está en condiciones de solicitar un préstamo y devolver esta información.
public class Siscti_Cloud_Demotracion implements EntryPoint {
           
private final solicitudServiceAsync solService = GWT.create(solicitudService.class);

public void onModuleLoad()
{
           
final Button sendButton = new Button("Enviar");      //Botón de Envío
final TextBox nameField = new TextBox();              //Texto del nombre del usuario
nameField.setText("Usuario");
                       
final TextBox emailField = new TextBox();              //Texto del nombre del email
emailField.setText("Email");
                       
final Label errorLabel = new Label();

sendButton.addStyleName("sendButton");               //Estilo del botón

                       
RootPanel.get("nameFieldContainer").add(nameField);     
RootPanel.get("emailFieldContainer").add(emailField);                             
RootPanel.get("sendButtonContainer").add(sendButton);
RootPanel.get("errorLabelContainer").add(errorLabel);

                       
nameField.setFocus(true);                                                                                                   nameField.selectAll();
                                                                                                                                             //Manejador
class MyHandler implements ClickHandler
{
            public void onClick(ClickEvent event) {
            enviarsolicitud();
            }

            private void enviarsolicitud()
            {
            String usuario = nameField.getText();
            String email = emailField.getText();
            solService.solicitud(email, usuario,new AsyncCallback()
            {
                        public void onFailure(Throwable c)
                        {
                                   Window.alert("Error");
                        }
           
                        public void onSuccess(Boolean result)
                        {
                                   if(result == Boolean.TRUE)
                                   {
                                               Window.alert("solicitud Aprobada");
                                   }
                                   else
                                   {
                                               Window.alert("solicitud Rechazada");
                                   }
                        }                                                         
                                                                      
            });
 }
}

//Manejador al Server
            MyHandler handler = new MyHandler();
            sendButton.addClickHandler(handler);
}
Code 5- Invocación del servicio.
El code 5 muestra la implementación del servicio, donde en primer lugar se arma la UI para colocar controles en donde el usuario pueda ingresar los datos del e-mail, nombre de usuario y el botón de acción. Luego se implementa el “ClickHandler” del botón, para finalmente implementar el método ”enviarSolicitud” que realizar la invocación al servicio y propone dos caminos,  “Failure” o “Success” por el camino exitoso se evalúa la respuesta y se muestra el resultado al usuario. Para remarcar es necesario aclarar que esta interacción representada se realiza de forma asincrónica y la estructura plantea como pueden observar en el Code 5 la posibilidad de manejar una excepción que puede desencadenarse por varios motivos pero en los escenarios de comunicación son notoriamente más críticos. En el ejemplo representado en el Code 5, podemos observar que en el evento “onFailure” se recibe como parámetro un objeto de tipo “Throwable” que trae consigo mucha información de la excepción en el caso de desencadenarse, igualmente la implementación mostrada solo muestra un mensaje materializando un error, no brinda información extra.
Para completar este articulo, les dejo el diseño vinculado a la página de visualización html, “Siscti_Cloud_Demotracion.html”



Code 6 - Html de implementación del servicio.
El code 6 muestra resaltado el enlace con los controles programados en el entrypoint para la operación de invocación del servicio de solicitudes.


La Fig 6 muestra el resultado final de la página.
Fig. 6 - Muestra de la página final mostrada al usuario.

Les dejo la implementación en el siguiente vídeo.


Espero les sea de utilidad…

Comentarios

  1. Muy buena tu página, me gustó mucho el diseño. Soy Eduardo Ibarra, quien trabajó en Socializer.

    Un saludo!

    ResponderBorrar

Publicar un comentario

Entradas más populares de este blog

Modelando relaciones en UML, un acercamiento a las Asociaciones

Utilizando Intents implícitos para crear actividades

Secuencias…Modelado indispensable