Tutorial: Creating a Remote Service with GWT Designer
This tutorial demonstrates how to create a Remote service with GWT and GWT Designer. It takes the GWT Tutorial on RPC and adapt it for GWT Designer. Since this is a continuation of the Stock Watcher tutorial, you might want to read through that first or download the project here.
Prerequisites:
Note: This tutorial was created using Eclipse 3.4, Java 1.6, GWT v1.5 and GWT Designer v5.1.
Special thanks to Chad Lung for creating this tutorial.
First, have a look at the GWT Getting Started Tutorial on RPC.
In the Stock Watcher tutorial, we built the Stock Watcher web app. It worked
fine but did ignore one major thing: The stock data is generated in the
browser via JavaScript. In a real world web application we would pull
our stock data from a server - whether it was from our own server or
from some other server out in the cloud. We are going to modify the Stock Watcher app to use RPC (Remote Procedure Call) to update the stock information. The really
cool thing is we can reuse the logic we wrote (well, actually the GWT
Team wrote it first!) to randomly generate the stock prices since its
all in Java and we can do so with very minor changes. We will host that
logic in a Java Servlet which is a pretty standard place to do such a thing and is very common in the Java world.
To create the RPC service while following the GWT RPC Tutorial takes a few steps, using GWT Designer is much less work for us. If you
haven't opened the StockWatcher project do so now. Once its open expand
the project items out like the following:

Right-click on the com.google.gwt.sample.stockwatcher.client.StockWatcher.client package
and choose: Google Web Toolkit -> GWT remote service.

On the next windows that pop up we are going to use the name: StockPriceService.

Lets see what happened now. The GWT Designer basically did a lot of work for us. First, three files were created.
- StockPriceService.java
- StockPriceServiceAsync.java
- StockPriceServiceImpl.java

Also, in the StockWatcher.gwt.xml file you will see an entry for our servlet was added:
<servlet path="/StockPriceService" class="com.google.gwt.sample.stockwatcher.client.StockWatcher.server.StockPriceServiceImpl"/>
Lets move into the StockPriceService.java first. Open up that file
in the source editor and have a look around. We need to add the
following code (notice how the method signature is just like the
function of the same name in the first tutorial - but that one is
executed on the client, this one will be executed on the server):
StockPrice
[] getPrices
(String[] symbols
);
So our code then looks like this:
package com.
google.
gwt.
sample.
stockwatcher.
client.
StockWatcher.
client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@RemoteServiceRelativePath("StockPriceService")
public interface StockPriceService extends RemoteService
{
StockPrice[] getPrices(String[] symbols);
/**
* Utility class for simplifying access to the instance of async service.
*/
public static class Util
{
private static StockPriceServiceAsync instance;
public static StockPriceServiceAsync getInstance()
{
if (instance == null)
{
instance = GWT.create(StockPriceService.class);
}
return instance;
}
}
}
Once you've done that hit the "Save" button in Eclipse. Now, a surprise happened behind our backs. Perhaps if you watched the RPC video I mentioned before you know what happened already. Give up? Well when
we added that code to StockPriceService.java file and hit "Save" GWT
Designer being smart went out and made some modifications to the
following files:
1. StockPriceServiceImpl.java
2. StockPriceServiceAsync.java
But what happened? Take a look at those files. Notice anything? GWT
Designer added that method we defined to those two files for us.
Obviously this is something we could have done ourselves, but its
certainly helpful that GWT Designer is smart enough to just do this by
itself. In fact if we were to rename this method or change it's
signature, GWT Designer will make the appropriate changes for us.
Lets fill in the implementation method for our service. You will
notice that the logic in the original tutorial "refreshWatchList()"
function is very similar to the logic we are now putting in the
"getPrices()" function. Move into the StockPriceServiceImpl.java file
and modify it to look like this:
package com.
google.
gwt.
sample.
stockwatcher.
client.
StockWatcher.
server;
import com.google.gwt.sample.stockwatcher.client.StockWatcher.client.StockPrice;
import com.google.gwt.sample.stockwatcher.client.StockWatcher.client.StockPriceService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.Random;
public class StockPriceServiceImpl extends RemoteServiceServlet implements
StockPriceService
{
private static final double MAX_PRICE = 100.0;
private static final double MAX_PRICE_CHANGE = 0.02;
@Override
public StockPrice[] getPrices(String[] symbols)
{
Random rnd = new Random();
StockPrice[] prices = new StockPrice[symbols.length];
for (int i = 0; i <symbols.length; i++)
{
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;
}
}
So the logic is very similar to the "refreshWatchList()" function, but what about this:
Since we are now running this code on the server vs. the client we
make use of the java.util.Random library rather than the emulated GWT
version in com.google.gwt.user.client.Random.
Now up until now we haven't talked about Asynchronous calls - which is what we are going to be doing. I'll point you to the GWT RPC Tutorial for a great explanation and say this: Asynchronous calls help with
performance since they don't block the application waiting for a return
call. You can also make multiple calls and do other things while
awaiting for replies to your calls. In today's web applications
asynchronous calls have become a standard practice for many developers.
We now need to open the StockPrice.java file and make some modifications. We need to make this class serializable so the data can go across the wire via RPC. We'll need to add an import in order to have the serialization support:
import com.google.gwt.user.client.rpc.IsSerializable;
We can now change the following code from this:
public class StockPrice
To this:
public class StockPrice implements IsSerializable
Ok believe it or not we are done with the server piece of this
project. We are going to move on to the client code now. Open up the
StockWatcher.java file and add this import:
import com.google.gwt.user.client.rpc.AsyncCallback;
Remove this import since it is going to be unused soon (remember we
moved the logic that uses the random numbers stuff to the server):
import com.google.gwt.user.client.Random;
This next step you need to keep in mind that there are different ways to
do this. I'm going to take an easy route for the sake of simplicity. Go
into the "refreshWatchList()" function and remove the code in there and
replace it with our call to the Asynchronous RPC call to our servlet:
protected void refreshWatchList
()
{
StockPriceService.
Util.
getInstance().
getPrices(stocks.
toArray(new String[0]),
new AsyncCallback<StockPrice
[]>
() {
public void onSuccess
(StockPrice
[] result
)
{
updateTable
(result
);
}
public void onFailure(Throwable caught)
{
// Error: Whoops!
}
});
}
Assuming everything went well we can now run this and hopefully you will see something similar to this:

It sure looks like the same old web app we built in the first
tutorial, but how do we really know its getting its "fake" data from
the server via RPC? We can verify this by pressing the "Compile/Browse"
button on the GWT Browser which will open up your default web browser,
in my case it is Firefox 3 which has Firebug 1.2 installed.

Then I can open Firebug and drill into the browser traffic to see that indeed I'm talking to the server.

That concludes this tutorial. You can download the source file from here.
You can post your comments, questions, corrections in the GWT Designer forum.
Related topics: