Google Web Toolkit (GWT) and Java Servlets used in one web application. This tutorial will take you though the steps of developing a simple web application with Google Web Toolkit and J2EE Servlet Technology. The application will have a servlet on server side and one web page.Prerequisites
- Better to be familiar with developing web applications with J2EE/Servlets
- Knowledge on deploying a web application into Tomcat web server
System Requirements
In brief, GWT is a framework for developing Ajax based web pages with Java. All the HTML page content will be written as Java classes and converted into a set of Javascript files. For more information on GWT, refer to official site here. http://code.google.com/webtoolkit/Introduction
In this tutorial we will create a simple web application which has one page. When a user clicks a button, web page content will be updated without refreshing or leaving the current page. But the web page will talk to a servlet deployed in web server and update the page content. The communication between web server and browser will be invisible to the user, providing a convenient web experience. Even though this is a simple application, it represents a main concept of any advanced application implemented with GWT.Implementation
The development work is broken down into 7 steps and each will be discussed in details.- Create a java web project with GWT
- Data Service - server & client side
- Widget (component displayed on web page)
- Entry point
- Web page (html/jsp)
- Module XML
- Compile and deploy
eg: $GWT_HOME=C:\java\gwt-windows-1.4.61
1. Create a java web project with GWT
To start with, we need to create a java project. GWT comes with a script to create a java project according to the recommended project structure. It is called "applicationCreator"; applicationCreator.cmd is available inside $GWT_HOME directory.$GWT_HOME> applicationCreator -out C:/samples/GWT-Sample
org.kamal.hello.client.HelloWorld
For parameter named "out" you must provide the location to create the new project. Also a class name must be provided for this command. This class is called Entry point class (we'll be touching this class later).
Above command creates a project named GWT-Sample in the destination location and created project would look as follows.
It will contain a Java class (Entry point class), a HTML page and a XML file (called Module XML). This module xml file will also be discussed later. For the time, better note the path to this file: org/kamal/hello/HelloWorld.gwt.xml.2. Data Service - server & client side
For our application we need a service that provides data for our client side page. So we'll define this service to have only one method returning a String. This service will be provided through a servlet which is running on a server side. Generally we would write only a single servlet that extends from javax.servlet.http.HttpServlet, but in GWT we must define two interfaces inside client package (org.kamal.hello.client) along with the servlet. However these two interfaces are quite simple.i). Service interface
The services provided by the server-side must be declared in a Service interface first. The methods declared in the Service interface will be available to the client side. It is only a simple interface which must extend com.google.gwt.user.client.rpc.RemoteService interface. We will define the service interface with only one method that returns a string.package org.kamal.hello.client;
import com.google.gwt.user.client.rpc.RemoteService;
public interface DataService extends RemoteService {
public String getData();
}
ii). Asynchronous Service interface
Next we will define another interface called "Asynchronous interface". This interface is used to define the asynchronous feature of the service. That is when ever a call is made to this interface, the caller can expect the service to be asynchronous and the result will be available after sometime. The caller must provide a callback object to receive the resulting data. There are some important points to note.- Asynchronous interface must be in the same package as the service interface
- This interface's name must be as <Service-Interface-Name>Async (same name with Async suffix)
- Add a new parameter of type com.google.gwt.user.client.rpc.AsyncCallback to parameter list of every method.
- All methods must have void as return type
package org.kamal.hello.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface DataServiceAsync {
public void getData(AsyncCallback callback);
}
The above interface is named DataServiceAsync (using DataService + Async) and the DataService.getData() method is provided with a new parameter while having void return type.
iii). Service servlet
Now we can define the service servlet which does the actual work. This class must implement above declared DataService interface and extend the com.google.gwt.user.server.rpc.RemoteServiceServlet class.package org.kamal.hello.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.*;
import org.kamal.hello.client.DataService;
public class DataServiceImpl
extends RemoteServiceServlet implements DataService {
public String getData() {
int key = (int)(Math.random()*3);
return (String)data.get(String.valueOf(key));
}
private static Map data = new HashMap();
static {
data.put("0", "Hi, This is Server");
data.put("1", "How are you?");
data.put("2", "It’s too warm here at Server");
}
}
Above class implements the getData() method of DataService interface and returns a String with simple logic. Even though we call this a servlet, no servlet specific implementation is available, so is this a servlet? Yes, it is; the super class, RemoteServiceServlet is a servlet.
iv). Servlet configuration (web.xml)
Now we have to specify the servlet in a web.xml file. (Do not worry even if you are not much familiar with web.xml, everything needed is listed below).Create a file named web.xml inside GWT-Sample project folder with the following content.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>DataService</servlet-name>
<servlet-class>
org.kamal.hello.server.DataServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataService</servlet-name>
<url-pattern>
/org.kamal.hello.HelloWorld/data
</url-pattern>
</servlet-mapping>
</web-app>
Here we have defined a url pattern for our above mentioned DataServiceImpl servlet. Note the way this url pattern (/org.kamal.hello.HelloWorld/data) is defined.
First part of the url pattern org.kamal.hello.HelloWorld is derived from the path to Module XML file which is org/kamal/hello/HelloWorld.gwt.xml. The rest of the url pattern can be selected arbitrarily, better to use a declarative word.
3. Widget (component displayed on web page)
Now we must create the widget that will be displayed in the web page of our web application. The widget coding is listed below.package org.kamal.hello.client.widgets;
import com.google.gwt.core.client.*;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.ui.*;
import org.kamal.hello.client.*;
public class HelloWidget extends Composite {
public HelloWidget() {
// obtain a reference to the service
service = (DataServiceAsync) GWT.create(DataService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) service;
endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "data");
initWidget(panel);
panel.add(label, DockPanel.CENTER);
panel.add(button, DockPanel.SOUTH);
// click listener to get data from server
button.addClickListener(new ButtonClickListener());
}
private class ButtonClickListener implements ClickListener {
public void onClick(Widget sender) {
// call servlet to get data
service.getData(new AsyncCallback() {
public void onFailure(Throwable e) {
label.setText("Server call failed");
}
public void onSuccess(Object obj) {
if (obj != null) {
label.setText(obj.toString());
} else {
label.setText("Server call returned nothing");
}
}
});
}
}
private final DataServiceAsync service;
private final DockPanel panel = new DockPanel();
private final Button button = new Button("Talk");
private final Label label = new Label("Welcome, talk to server");
}
This widget contains one label and one button. It uses a reference of type DataServiceAsync to communicate with the DataServiceImpl servlet deployed on a web server. You must pay attention to the way this DataServiceAsync reference is obtained.
HelloWidget.ButtonClickListener class is there to respond to onClick() action of the button. Inside this class an implementation of AsyncCallback is used to get data from the DataServiceAsync reference and to update the label content.
4. Entry point
Entry point class was generated while creating the project at step 1 of this tutorial with the class name org.kamal.hello.client.HelloWorld. This is the class used to load the widget into the web page. Inside the onModuleLoad() method, we have accessed an element named "content"; this element must present in the web page that we are expecting to load the widget. Then the HelloWidget; the widget we created above is added into this element.package org.kamal.hello.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import org.kamal.hello.client.widgets.HelloWidget;
public class HelloWorld implements EntryPoint {
public void onModuleLoad() {
// set widget on "content" element
RootPanel content = RootPanel.get("content");
if (content != null) {
content.add(new HelloWidget());
}
}
}
5. Web page
Following is the page that we will be using to load our HelloWidget. This page is already available inside GWT-Sample1\src\org\kamal\hello\public folder. Edit this page to have the following coding.This page contains an element with id="content", which is used to load the newly created widget into this page. Also note that a .js file has been imported into this page. We will be generating this org.kamal.hello.HelloWorld.nocache.js file in a following step.
<html>
<head>
<title>HelloWorld</title>
<script language="javascript"
src="org.kamal.hello.HelloWorld.nocache.js">
</script>
</head>
<body>
<h1>HelloWorld</h1>
<table align="center" width="100%">
<tr>
<td id="content"></td>
</tr>
</table>
</body>
</html>
6. Module XML
This is the module configuration (module xml) file. The entry point class is specified in this module xml. This file is also autogenerated in step 1, and it is stored inside "org\kamal\hello" folder.<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name="com.google.gwt.user.User" />
<!-- Specify the app entry point class. -->
<entry-point class="org.kamal.hello.client.HelloWorld" />
</module>
7. Compile and deploy
We have created all the required classes and files. Now we must generate Javascripts from above created Java classes. Then compile and deploy the project.i). Generate Javascript from Java classes
For generating Javascript files from Java classes we will use the HelloWorld-compile.cmd, which was generated into the project folder in the step 1. You just have to run this command file without any parameters.GWT-Sample> HelloWorld-compile.cmd
This will create a new folder named "www" inside GWT-Sample project folder, and it will contain a set of web resources including "org.kamal.hello.HelloWorld.nocache.js" file which we used in step 5.
ii). Compile classes
Now create a folder named "WEB-INF" inside "www" folder. Then create two folders named "classes" and "lib" inside this WEB-INF folder.Now compile service related Java classes that we created up to now into this www/WEB-INF/classes folder.
GWT-Sample\src> javac -cp $GWT-HOME/gwt-user.jar
-d ../www/WEB-INF/classes
org/kamal/hello/client/Data*.java
org/kamal/hello/server/*.java
Now copy $GWT-HOME/gwt-servlet.jar file into the www/WEB-INF/lib folder.
GWT-Sample> copy $GWT-HOME\gwt-servlet.jar www\WEB-INF\lib
Note: we use gwt-user.jar to compile while gwt-servlet.jar at deployment. (you can read the reason here).
Copy GWT-Sample/web.xml into www/WEB-INF folder.
iii). Deploy into web server
Create a folder named "GWT-Sample" inside $CATALINA_HOME/webapps and copy "www\org.kamal.hello.HelloWorld" and "www\WEB-INF" folders into that "GWT-Sample" folder (shown above). Now everything is completed. Start Tomcat and try the following URL from your browser.
http://localhost:8080/GWT-Sample/org.kamal.hello.HelloWorld/HelloWorld.html
Now you will see the web page with the label text and button as shown in the image. Play around by clicking the button to see different messages coming from the server. The web page will not be re-fetched from the web server, but only the text of the label will be refreshed.Even though this is a pretty simple application, you can use this concept to develop advanced applications.
Labels: GWT, Java, Javascript, Tutorial
Translate into your language
Reader Comments
Search More Articles

Kamal Mettananada is a Software Architect, Java Explorer and Blogger. Digizol consists of computer related articles, tutorials, tips and other information.
Thank you,
Roger
Thanks.
my endpoint is defined with: endpoint.setServiceEntryPoint(GWT.getModuleBaseURL());
web.xml:
servlet
servlet-name Service /servlet-name
servlet-class com.xyz.server.ServiceImpl /servlet-class
/servlet
servlet-mapping
servlet-name Service /servlet-name
url-pattern /com.xyz.MyApp/
/url-pattern
/servlet-mapping>
Deployed application works except RPC methods fails with message
"The requested resource (/GWT-Sample/com.xyz.MyApp/) is not available."
what do i wrong?
For url-pattern we have used;
/org.kamal.hello.HelloWorld/data
Module path: /org.kamal.hello.HelloWorld/
service name: data
Please change your url-pattern and try again.
When I run in hosted mode I get the following errors after hitting the "Talk" button:
1) Server call failed (on the window)
2) Log shows
"The development shell servlet received a request for 'data' in module 'org.kamal.hello.HelloWorld.gwt.xml'"
"Resource not found: data; (could a file be missing from the public path or a /servlet/ tag misconfigured in module org.kamal.hello.HelloWorld.gwt.xml.
I followed the steps, I am not sure whats wrong. Any help would be appreciated.
thanks,
Feroza
servlet path="/data" class="org.kamal.hello.server.DataServiceImpl"
(Note: add the <> around the above statement, I couldnt do it due to posting parser)
Do you know of any good seam/gwt examples that will also work in hosted mode? The gwt example delivered with seam doesnt seem to work.
thanks,
Feroza
I got the server up and running but I'm getting a server call failed message.
i'm stuck at creating the .js
do u know how to create .js in this case?
thank u for ur lecture
Thanks for tutorial - and thanks anonymous for servlet path info, you saved me much time. It would have been good if it worked out of the box in hosted mode, but still very helpful.
Brianoh
in the *.gwt.xml write
servlet path="/DataService" class="(path).DataServiceImpl"
Please send me any link of any of your other tutorial on gwt to junaid.rehman@yahoo.com
Really appriaciate you...
I had big trouble with the right settings in web.xml. Always get an error: "requested resource [/(path)/DataService] is not available".
Finally I cleaned my TOMCAT/webapps folder and it worked - so not every error is an gwt problem. Thx...
Very helpful
Thank you
Regards,
Sangeetha Aswin
I have added the line "servlet path="/data" class="org.kamal.hello.server.DataServiceImpl" " to my HelloWorld.gwt.xml and all runs well when in hosted mode.
but i get the following error when i attempt to run on my server:
Server call failed.....
404 Not Found
Not Found
The requested URL /GWT-Sample/org.kamal.hello.HelloWorld/data was not found on this server
Do i need to add that line to my web.xml file ?
Also, i do not see the HelloWorld.gwt.xml in my classes folder (i have no public folder)?
Do i need one or is this taken care of behind the scenes.
Many thanks
I can get it working with GWT in Eclipse.
But after deployment to the real TOMCAT server, I get the server call failed error .......
I have added the servlet in the web.xml file.
working fine in hosted mode...but when deployed on webserver, i'm getting a server call failed....
anyone; please reply...
I'm implementing a .pdf view in servlet, and I was getting the same problem: fine in GWT hosted mode, 404 Not Found when deployed to Webshpere.
Solved it by making sure I had the full path specified in the web.xml servlet mapping. Ie:
Old failing web.xml (replace curly braces with angle brackets as appropriate - stupid blogspot):
{servlet-mapping}
{servlet-name}PDFServlet{/servlet-name}
{url-pattern}/pdf/document.pdf{/url-pattern}
{/servlet-mapping}
New working web.xml:
{servlet-mapping}
{servlet-name}PDFServlet{/servlet-name}
{url-pattern}/au.com.mycompany.myapp.MyApp/pdf/document.pdf{/url-pattern}
{/servlet-mapping}
Hope this helps someone!
PS: also need the sevlet specified in MyApp.gxt.xml as #12 said.
Post a Comment
We appreciate your opinions, suggestions and criticism.