martes, 23 de agosto de 2011

GWT - RPC

GWT provides a few different ways to communicate with a server. Which data format you use will ultimately depend on the server you need to interact with.

  • Making Remote Procedure Calls (GWT RPC)
  • Retrieving JSON Data via HTTP
  • Making Cross-Site Requests for JSONP

GWT - RPC

Whether you use GWT RPC or get JSON data via HTTP, all the calls you make from the HTML page to the server are asychronous
The GWT RPC framework makes it easy for the client and server components of your web application to exchange Java objects over HTTP. The server-side code that gets invoked from the client is often referred to as a service. The implementation of a GWT RPC service is based on the well-known Java servlet architecture. Within the client code, you'll use an automatically-generated proxy class to make calls to the service. GWT will handle serialization of the Java objects passing back and forth—the arguments in the method calls and the return value. 
Definición extraida del sitio oficial del GWT (ver bibliografia)

In GWT, an RPC service is defined by an interface that extends the GWT RemoteService interface


Ejemplo de implementación de un RPC-Service


StockPriceService (paquete ...stockwatcher.client)

public interface StockPriceService extends RemoteService {


// Metodo que dado un symbol nos devolvera un price.
StockPrice getPrices(String symbol);
}

StockPriceServiceImpl (paquete ...stockwatcher.server)

public class StockPriceServiceImpl extends RemoteServiceServlet implements StockPriceService {


public StockPrice getPrices(String symbolId) {
return new StockPrice(symbolId, 899);
}
}

StockPriceServiceAsync (paquete ...stockwatcher.client)

Tip: The Google Plugin for Eclipse will generate an error when it finds a synchronous remote service without a matching asynchronous interface. You can right click on the error in Eclipse, select Quick Fix, and choose the "Create asynchronous RemoteService interface" option to automatically generate the asynchronous interface.


public interface StockPriceServiceAsync {


        void getPrice(String symbolId, AsyncCallback<StockPrice> callback);
}

Una vez creado el service (servlet), vamos a incluirlo en el modulo GWT. A partir de la version 1.6, los servlets los definiremos en el web.xml en lugar del StockWatcher-gwt.xml.


web.xml

  <!-- Servlets -->
  <servlet>
    <servlet-name>stockPriceServiceImpl</servlet-name>
 <servlet-class>com.google.gwt.sample.stockwatcher.server.StockPriceServiceImpl
      </servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>stockPriceServiceImpl</servlet-name>
    <url-pattern>/stockwatcher/stockPrices</url-pattern>
  </servlet-mapping>

NOTA:

In the <servlet-mapping> element, the url-pattern can be in the form of an absolute directory path (for example, /spellcheck or /common/login). If you specify a default service path with a @RemoteServiceRelativePath annotation on the service interface (as you did with StockPriceService), then make sure the url-pattern matches the annotation value. Because you've mapped the StockPriceService to "stockPrices" and the module rename-to attribute in StockWatcher.gwt.xml is "stockwatcher" (<module rename-to='stockwatcher'>), the full URL will be: http://localhost:8888/stockwatcher/stockPrices


Llamando a los métodos remotos

When you call a remote procedure, you specify a callback method which executes when the call completes. You specify the callback method by passing an AsyncCallback object to the service proxy class. The AsyncCallback object contains two methods, one of which is called depending on whether the call failed or succeeded: onFailure(Throwable) and onSuccess(T).

private StockPriceServiceAsync stockPriceSvc = GWT.create(StockPriceService.class);


stockPriceSvc.getPrice(symbol, new AsyncCallback<StockPrice>() {

@Override
public void onSuccess(StockPrice result) {


updatePrice(result);
}

@Override
public void onFailure(Throwable caught) {

System.out.println("onFailure....");
}
});

Manejo de excepciones

Agregar throws DelistedException en la interface StockPriceService y StockPriceServiceImpl

y Luego procedemos a capturar la excepcion de la siguiente manera:

stockPriceSvc.getPrice(symbol, new AsyncCallback<StockPrice>() {
@Override
public void onSuccess(StockPrice result) {

System.out.println("onSuccess INICIO ....");
setStockPrice(result);
System.out.println("price " + result.getPrice());
System.out.println("onSuccess FIN ....");
}
@Override
public void onFailure(Throwable caught) {
System.out.println("onFailure INICIO ....");
       String details = caught.getMessage();
       if (caught instanceof DelistedException) {
         details = "Company '" +
                                     ((DelistedException)caught).getSymbol() + 
                                     "' was delisted";
       }
       errorMsgLabel.setText("Error: " + details);
       errorMsgLabel.setVisible(true);
       System.out.println("onFailure FIN ....");
}
});




Bibliografia

No hay comentarios:

Publicar un comentario