Anatomy of RPC in GWT

When you create a new GWT project from sample code, you will get a widget with ajax capability, as GWT is meant to do javascript programming in Java language, what you see from this sample project are all Java code, if you want to understand this in a manner of client and server separation, there will be some miles to cover to get there.

Ajax in essence is a javascript client calling a web service, in GWT sample project, the service could be implemented in any server language, and using different protocols like soap, rest, in this case it is RPC and server implementation is Java.

The convenience of using RPC in GWT is that you can program an ajax enabled javascript widget in complete Java environment without any thought of what it looks like in javascript

But anatomy of RPC remote service will be helpful later on when we change our remote service to more general cases like a restful service with json. Here I would like to use StockPriceService sample to explain essential components of RPC ajax in GWT

Part 1: RPC Service Interface:

A service interface is the agreement between the client and server

In this case , it is an interface StockPriceService defined in StockPriceService.java in client name space, and it must extend com.google.gwt.user.client.rpc.RemoteService

@RemoteServiceRelativePath("stockPrices")
public interface StockPriceService extends RemoteService  {
	StockPrice[] getPrices(String[] symbols)  throws DelistedException;
}

Part2: Then RPC server side, service provider to implement service

This is actual implementation of the interface StockPriceService on server side, it also needs to extend RemoteServlet to be available from web, nothing too fancy

public class StockServiceImpl extends RemoteServiceServlet implements
		StockPriceService {

	private static final double MAX_PRICE = 100.0; // $100.00
	private static final double MAX_PRICE_CHANGE = 0.02; // +/- 2%

	@Override
	public StockPrice[] getPrices(String[] symbols) throws DelistedException {
		Random rnd = new Random();

		StockPrice[] prices = new StockPrice[symbols.length];
		for (int i = 0; i < symbols.length; i++) {

			if (symbols[i].equals("ERR")) {
				throw new DelistedException("ERR");
			}

			double price = rnd.nextDouble() * MAX_PRICE;
			double change = price * MAX_PRICE_CHANGE
					* (rnd.nextDouble() * 2f - 1f);

			prices[i] = new StockPrice(symbols[i], price, change);
		}

		return prices;

	}

}

In web.xml to publish the above servlet

<servlet>
    <servlet-name>stockPriceServiceImpl</servlet-name>
    <servlet-class>gwt.stockwatcher.server.StockServiceImpl</servlet-class>
  </servlet>

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

Part 3: RPC Client

Normally an ajax client, you will need a service url, in this case it is defined in @RemoteServiceRelativePath annotation, and be aware of that it is relative to your gwt module path, and it supports ‘..’ to access parent path

The other important component of ajax client is data contract, this is done in plain java object StockPrice.java, and it must implement com.google.gwt.user.client.rpc.IsSerializable, all data serialization is taken care of by gwt
And final step is to actual embed the service call in the widget, this is where StockPriceServiceAsync comes into play, in server languages, a method call can always be done asynchronous with a callback to notify the result of execution.

And the service consumption is

// Initialize the service proxy.
		if (stockPriceSvc == null) {
			stockPriceSvc = GWT.create(StockPriceService.class);
		}

		// Set up the callback object.
		AsyncCallback<StockPrice[]> callback = new AsyncCallback<StockPrice[]>() {
			public void onFailure(Throwable caught) {
			       // If the stock code is in the list of delisted codes, display an error message.
		        String details = caught.getMessage();
		        if (caught instanceof DelistedException) {
		          details = "Company '" + ((DelistedException)caught).getSymbol() + "' was delisted";
		        }

		        errorMsgLabel.setText("Error: " + details);
		        errorMsgLabel.setVisible(true);

			}

			public void onSuccess(StockPrice[] result) {
				updateTable(result);
			}
		};

		// Make the call to the stock price service.
		stockPriceSvc.getPrices(stocks.toArray(new String[0]), callback);

Tags:

This entry was posted on Friday, July 29th, 2011 at 3:14 am and is filed under Java, Javascript. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Response to “Anatomy of RPC in GWT”

  1. Rena says:

    Articles like this are an exmpale of quick, helpful answers.

Leave a Reply

*