Google WebToolkit remoting
Last week I started playing around with the google webtoolkit an Ajax framework that allows software engineers to develop complex ajax web interfaces in java rather than javascript.
I found the google webtoolkit not without it’s limitations, most noteably it is very hard to style / layout pages compared to jsp templates etc. But I do think it has potential for certain types of applications. While I struggled with other component based frameworks such as jsf, tapestry and wicket GWT was really easy to get into even though the documentation is currently still lacking and without compare to that offered by the aformentioned frameworks.
GWT comes with its own rpc framework. I’ll give you an example of how this works
You start out by defining your service interface
public interface HelloService extends RemoteService {
String sayHello(String name);
}
Service interfaces should allways extend from the RemoteService marker interface. Then you create an asychronous companion interface
public interface HelloServiceAsync {
void sayHello(String name, AsyncCallback callback);
}
The relationship between a service interface and its asynchronous counterpart is straightforward:
If a service interface is called com.example.HelloService , then the async interface must be called com.example.HelloServiceAsync. The async interface must be in the same package and have the same name, but with the suffix Async.
I actually don’t like having to repeat myself like this but i suppose it can’t be helped, eventually the code will get translated to javascript and as I understand it all javascript code runs within the context of a single thread. You can’t have a method blocking for 5 seconds while waiting for a response from the server because it would effectively make your application nonresponsive. If you ever played around with DWR you should be familiar with this pattern.
Implementations of the remote interface extend from RemoteServiceServlet which is a thin layer on top of HttpServlet. and takes care of serializing / deserializing arguments and response objects.
public class HelloServiceImpl extends RemoteServiceServlet implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}
Once you have this it is very simple to write a simple client.
public class Hello implements EntryPoint {
private HelloServiceAsync helloService;
public void onModuleLoad() {
helloService = (HelloServiceAsync) GWT.create(HelloService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) helloService;
endpoint.setServiceEntryPoint(“/helloservice”);
HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.add(new Button(“Say hello to jelmer”, new ClickListener() {
public void onClick(Widget sender) {
helloService.sayHello(“jelmer”, new AsyncCallback() {
public void onSuccess(Object result) {
String message = (String) result;
Window.alert(message);
}
public void onFailure(Throwable caught) {
}
});
}
}));
RootPanel.get().add(buttonPanel);
}
}
This will add a button to your page. when pressed it will call sayHello on the remote interface and display the resulting message in a javascript alert box.
Overall i turned out to be pretty easy and painless to create some (relatively) sophisticated functionality. The resulting code is very clean, strongly typed and you can use you favorite java ide to write it, so you have autocompletion and all that goodness available to you