GWT and Spring (Part 4) – GWT and Spring Integration using DWR and JSNI
Update 7/9/2010 – MyEclipse for Spring 8.6 now generates full ready-to-run GWT applications based on MVP and UI Binder in minutes. Just point the scaffolding wizard at your database tables, Java beans, or JPA Entities. You can learn more about it from the Generating Enterprise Class GWT applications for Spring post that I wrote on Genuitec blog. Or, you can keep reading my original post…
In part one we installed the Skyway Builder plugins and the Google Plugins for Eclipse, and we created the GWT project (dynamic web project) and the Spring DSL project. In part two we implemented the back-end of the GWT application using Spring and Direct Web Remoting (DWR). In part three we started to create the GWT front-end. In this post I’ll wrap up the implementation of the front-end, including the integration between GWT and DWR using GWT JavaScript Native Interface (JSNI).
Step 15: Create client model package
For a GWT application there is Java code that’s expected to be run on the server, and there’s Java code that’s expected to be translated into javascript to be run in a web browser. The key point is that not all the Java source code in your project needs to be translated to javascript. By default GWT will translate all code in the client sub-package, which was created for us when the entry point class was created in part 3. Any Java code we add to the client sub-package will be translated by GWT into javascript.
Some Java code generated by Skyway Builder (in part 2) can also be used to implement the front-end. In order to use the Java code in the front-end, it needs to be moved to the client sub-package (otherwise GWT won’t translate into javascript). We don’t want to just copy the generated code because if we implement changes to the back-end, we will need to remember to re-sync the front-end copy. That would be bogus. So instead we are going to slightly restructure the back-end application by creating a model package named org.todo.client and move the domain object from the org.todo.domain model package to the org.todo.client model package. Now any updates made to the domain model will automatically be propagated to the front-end.
Here are the steps:
- Create model package org.todo.client
- Move Task from org.todo.domain to org.todo.client
- Do Clean Build….code will be regenerated to reflect the new location (package) of the domain object
Now GWT can translate the Java code representing the domain object as needed.
Step 16: Add DWR includes into GWT application
The DWR testing page from part 2 provides you with the fragment of html that needs to be added to any HTML/browser-based application that needs to access the DWR services.

The fragment consists of several include statements for the javascript libraries that are dynamically generated by DWR. I haven’t spent any time really describing what DWR does or how it does it, but suffice it to say that DWR dynamically generates javascript libraries for accessing server-side logic. From a client-side development standpoint, the web developer just needs to call the javascript function corresponding to the server-side logic, and DWR takes care of the rest. In the context of this blog, Skyway Builder automatically performed the DWR configuration of the Spring application to generate the javascript functions for accessing the Spring @Services.
Copy the include statements from DWR test page into the Html page (todo.html) that was created in part 3.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>todo</title> <link href="style.css" rel="stylesheet" type="text/css" /> <script type='text/javascript' src='dwr/interface/TaskService.js'></script> <script type='text/javascript' src='dwr/engine.js'></script> <script type='text/javascript' src='dwr/util.js'></script> <script type="text/javascript" language="javascript" src="org.todo.Todo/org.todo.Todo.nocache.js"></script> </head>
<body> ..omitted for brevity </body> </html>
Step 17: Create List Widget
Now comes the fun part. There a variety of ways of implementing a GWT user interface. When I started experimenting with GWT I originally threw everything into the entry point class. I suppose it’s a perfectly acceptable way to start, but it’s definitely not very conducive to ongoing development. So I decided to break the user interface into components. Each component would be implemented in it’s own class, and the class would be responsible for rendering it’s portion of the user interface, handling it’s user events, and handling the calls to the server side logic. Components are called widgets in GWT, and they are implemented by extending the Composite class.
The first component I developed was the listing component.

This component contains a table (com.google.gwt.user.client.ui.FlexTable) and a button (com.google.gwt.user.client.ui.Button). When the “Load Data” button is clicked, the loadDataJSON() function is called, which uses GWT’s Javascript Native Interface (JSNI) to make a call to the TaskService.loadTasks() javascript function. This function is from the javascript library that was generated by DWR and included in the Html page in step 16. The loadDataJSON() function also defines the loadDataCallback() javascript function which is the callback handler for the TaskService.loadTasks() function. When DWR gets the response (hopefully with data) from the server, DWR will call the callback handler which in turn calls the filltable() function in the GWT class.
public native void loadDataJSON()/*-{
var foo = this;
$wnd.TaskService.loadTasks(loadDataCallback);
function loadDataCallback(data){
foo.@org.todo.client.TaskList::fillTable(Lcom/google/gwt/core/client/JsArray;)(data);
}
}-*/;
public void fillTable(JsArray data) {
//implementation omitted for brevity
}
Hopefully I didn’t overly complicate the description in the last paragraph. If so, you may need to read it more than once. The bottom line is that JSNI is an integral feature of GWT to make the integration with DWR work. Integrating Java and Javascript didn’t seem feasible to me originally, and at first I was a bit skeptical of JSNI. However having now worked with JSNI a bit, I can see the it not only works….it works really well.
From the code listing you can also see that I used GWT’s JSON support libraries for converting JSON data to and from Java. One additional noteworthy item is that the GWT class is using the domain object that was generated in part 2. The only thing that was done to the domain object to accommodate GWT was that it was moved to the client package (see step #15). So in addition to generating the entire back-end of this GWT application, Skyway Builder also generated some of the code that is used in the GWT front-end.
Step 18: Create Entry Form Composite
The next component is the entry form.

While the function of the entry form is fundamentally different from the List component, the integration to back-end integration is nearly identical.
public native void saveDataJSON(JavaScriptObject saveme)/*-{
var foo = this;
$wnd.TaskService.saveTask(saveme, replySave);
function replySave(data){
$wnd.alert("The data has been saved");
}
}-*/;
When the “Save” button is clicked, the saveDataJSON() function is called, which uses GWT’s Javascript Native Interface (JSNI) to make a call to the TaskService.saveTask() javascript function. The saveDataJSON() function also defines the replySave() javascript function which is the callback handler for the TaskService.saveTask() function.
Step 19: Update GWT Entry Point Class
With the UI components done, the components need to be included in the entry point class of the GWT application.
package org.todo.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
public class TodoApp implements EntryPoint {
private TaskForm xyz;
private TaskList mno;
@Override
public void onModuleLoad() {
xyz = new TaskForm();
mno = new TaskList();
RootPanel.get().add(mno);
RootPanel.get().add(xyz);
}
}
There really aren’t any surprises here. I think the code is pretty self explanatory.
Step 20: Run application
For running the application, we can use the app server included with the Google Eclipse Plugin. Right-click on TodoGWT project and select Run-As–>Web Application. This menu item is contributed by the Google Eclipse plugin, which will kick off the application running in the embedded app server.

In part 5 I will show how to deploy the application to Tomcat.
This series consists of five parts:
- Part 1 – Setup of development environment; Setup of the GWT project
- Part 2 – Scaffold Spring back-end for GWT application
- Part 3 – Create GWT Front-end Skeleton
- Part 4 – GWT and Spring Integration
- Part 5 – Deploy and Test GWT application on Tomcat
Tags: Code Generation, dwr, GWT, java, javascript, JSNI, JSON, ria, Skyway Builder 6.3








December 8th, 2009 at 7:14 pm
Maybe i’m missing something….
Why the heck use DWR *with* GWT :)?
Both tech’s have their place.. just seems.. academic to mix them
Not criticizing hah.. just missing the “big gain” from doing so
December 8th, 2009 at 8:07 pm
Nope. I think you’re right. I came to the same conclusion. I blogged about it here: http://www.skywayperspectives.org/blog/?p=1346