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.
This's an excellent article, I was able to get everything running.
ReplyDeleteThank you,
Roger
Best tutorial I read on gwt. Please write some more articles on Gwt.
ReplyDeleteThanks.
Good and complete tutorial, thank you.
ReplyDeleteI am trying to add the component to JSF page. This component makes RPC call. RPC call works fine it goes to throughthe servlet and loads the data. But I dont see the data in the component. Component is datatable. I see empty table.
ReplyDeleteThe best way to overcome this type of issue is to use the hosted mode.
ReplyDeleteThanks, a good tutorial.
ReplyDeletenice and clean tutorial.
ReplyDeleteReally useful article. It gives something tangible, something actionable....
ReplyDeleteThanks for this tutorial, but i still have problem with deploying.
ReplyDeletemy 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?
Seems you haven't follow the way we did in this tutorial.
ReplyDeleteFor 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.
Thank you for the great tutorial.
ReplyDeleteWhen 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
I got it working, I had to add a servlet path to HelloWorld.gwt.xml:
ReplyDeleteservlet 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
yes... the tag that "Anonymous" mentioned above is missing... please Kamal, add that to your tutorial.... thx
ReplyDeleteGreat Tutorial!
ReplyDeleteI got the server up and running but I'm getting a server call failed message.
Wish I would have found this page a few weeks ago. Could have saved be a couple hours. Nice write.
ReplyDeletethis is a nice example. however, im using eclipse+cypal.
ReplyDeletei'm stuck at creating the .js
do u know how to create .js in this case?
thank u for ur lecture
Hi,
ReplyDeleteThanks 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
Thank you! best tutorial than google provides but web.xml is not necesary:
ReplyDeletein the *.gwt.xml write
servlet path="/DataService" class="(path).DataServiceImpl"
Sir...I was searching for a simple gwt tutorial and now i get it here...it is very excellent tutorial..
ReplyDeletePlease send me any link of any of your other tutorial on gwt to junaid.rehman@yahoo.com
Really appriaciate you...
Thanks! Really great tutorial. A little bit to late for my programming, but by deploying the WAR it was helpfull.
ReplyDeleteI 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...
Really good tutorial
ReplyDeleteVery helpful
Thank you
Regards,
Sangeetha Aswin
Hi, please forgive my ignorance, i'm very new to this.
ReplyDeleteI 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
Thanks. But problems.
ReplyDeleteI 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.
hi i'm new to GWT,...how can i open a directory and count the no. of files in that directory in GWT....when I use java.io.File; it gives an error while running
ReplyDeleteindeed an excellent tutorial....
ReplyDeleteworking fine in hosted mode...but when deployed on webserver, i'm getting a server call failed....
anyone; please reply...
All,
ReplyDeleteI'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.
Thanks, a good tutorial, Can you do a favour? Can you also upload a sample tutorial showing some database operation? Basically one which makes a call to db, fetch data and display on the grid. This would surely help a lot for the novices like me. thanks for your time in advance/
ReplyDeleteHi, Thanks for your nice tutorial.I am getting error in step 7 , ii) compile classes.My $GWT_HOME is "D:/GWTFULL/gwt-windows-1.5.3" . While i am trying to compile classes as you said,i get the following error.
ReplyDeleteC:\>javac -cp D:/GWTFULL/gwt-windows-1.5.3/gwt-user.jar -d C:/samples/GWT_Sample
/www/WEB-INF/classes org/kamal/hello/client/Data*.java org/kamal/hello/server/*
.java
javac: file not found: org\kamal\hello\client\Data*.java
Usage: javac \options\ \source files\
use -help for a list of possible options
Nice tutorial ..
ReplyDeletehi, i have a quiestion....i deploy the application into the tomcat but i cant´t understard how the browser get a response from de server....why i don´t need to run my application???
ReplyDeleteHello sir,
ReplyDelete“Sir tell me how to add servlet into GWT project”
please help me, provide some steps to create a servlet into GWT application.
I want to upload a file through a servlet.
Its an awesome tutorial for those who want to have a hang on GWT.
ReplyDeleteActually I have followed one what ever you are disclosing here.
My application throws StatusCodeException in web-mode but it's working in hosted-mode. I am using IntelliJ Idea 8.1.3, tomcat 5.5, gwt 1.5.3, hibernate 3 and struts 1.3.
Perhaps I have mapped the servlet class wrongly in the web.xml. I am now in a jittery state as it's been almost a week I am trying to crack the code but in vain.
Please help me out
thanks very much .the best tutorial about GWT.how to make a link in GWT
ReplyDeleteBrother, nice explanation !!!
ReplyDeletevery fine artical good and write more such importent artical
ReplyDeleteThanks ! for this valuable knowledge. I really like your post as your post is very informative as well as interesting. I really want to see your upcoming post. so pleaser keep writing.
ReplyDeleteYour tutorial is so well done, it makes gwt an easy tool!...nothing like the official google tutorial. You should be working for google so we won't have to browse the web for explicite tutorials...
ReplyDeleteBest tutorial on GWT, ever.
ReplyDeletethanks!
hmm this site is really awesome and informative to me, i am also gonna share this site to my friends and buddies.
ReplyDeleteIt is a fabulous site and it is very clear how to create web apps using toolkit and java servlets.
ReplyDelete