Google Web Toolkit (GWT) & Servlets - Web application tutorial - Digizol6

Post Top Ad

Responsive Ads Here

Post Top Ad

Responsive Ads Here

Tuesday, September 2, 2008

Google Web Toolkit (GWT) & Servlets - Web application tutorial

GWT LogoGoogle 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

  • JDK installed
  • Apache Tomcat web server (download, any other web server can be used)
  • GWT (download)
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.
  1. Create a java web project with GWT
  2. Data Service - server & client side
  3. Widget (component displayed on web page)
  4. Entry point
  5. Web page (html/jsp)
  6. Module XML
  7. Compile and deploy
In this document $GWT_HOME is used to denote the directory where extracted GWT framework is available.
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.

GWT applicationCreator project structureIt 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.
  1. Asynchronous interface must be in the same package as the service interface
  2. This interface's name must be as <Service-Interface-Name>Async (same name with Async suffix)
  3. Add a new parameter of type com.google.gwt.user.client.rpc.AsyncCallback to parameter list of every method.
  4. 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


GWT web application deployed in TomcatCreate 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

GWT HelloWorld web application outputNow 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.

40 comments:

  1. This's an excellent article, I was able to get everything running.

    Thank you,
    Roger

    ReplyDelete
  2. Best tutorial I read on gwt. Please write some more articles on Gwt.

    Thanks.

    ReplyDelete
  3. Good and complete tutorial, thank you.

    ReplyDelete
  4. I 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.

    ReplyDelete
  5. The best way to overcome this type of issue is to use the hosted mode.

    ReplyDelete
  6. Thanks, a good tutorial.

    ReplyDelete
  7. nice and clean tutorial.

    ReplyDelete
  8. Really useful article. It gives something tangible, something actionable....

    ReplyDelete
  9. Thanks for this tutorial, but i still have problem with deploying.

    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?

    ReplyDelete
  10. Seems you haven't follow the way we did in this tutorial.

    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.

    ReplyDelete
  11. Thank you for the great tutorial.

    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

    ReplyDelete
  12. I got it working, I had to add a servlet path to HelloWorld.gwt.xml:

    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

    ReplyDelete
  13. yes... the tag that "Anonymous" mentioned above is missing... please Kamal, add that to your tutorial.... thx

    ReplyDelete
  14. Great Tutorial!

    I got the server up and running but I'm getting a server call failed message.

    ReplyDelete
  15. Wish I would have found this page a few weeks ago. Could have saved be a couple hours. Nice write.

    ReplyDelete
  16. this is a nice example. however, im using eclipse+cypal.
    i'm stuck at creating the .js
    do u know how to create .js in this case?

    thank u for ur lecture

    ReplyDelete
  17. Hi,
    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

    ReplyDelete
  18. Thank you! best tutorial than google provides but web.xml is not necesary:

    in the *.gwt.xml write

    servlet path="/DataService" class="(path).DataServiceImpl"

    ReplyDelete
  19. Sir...I was searching for a simple gwt tutorial and now i get it here...it is very excellent tutorial..
    Please send me any link of any of your other tutorial on gwt to junaid.rehman@yahoo.com
    Really appriaciate you...

    ReplyDelete
  20. Thanks! Really great tutorial. A little bit to late for my programming, but by deploying the WAR it was helpfull.

    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...

    ReplyDelete
  21. Really good tutorial
    Very helpful


    Thank you

    Regards,
    Sangeetha Aswin

    ReplyDelete
  22. Hi, please forgive my ignorance, i'm very new to this.
    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

    ReplyDelete
  23. Thanks. But problems.
    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.

    ReplyDelete
  24. 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

    ReplyDelete
  25. indeed an excellent tutorial....

    working fine in hosted mode...but when deployed on webserver, i'm getting a server call failed....

    anyone; please reply...

    ReplyDelete
  26. All,
    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.

    ReplyDelete
  27. 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/

    ReplyDelete
  28. Hi, 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.
    C:\>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

    ReplyDelete
  29. hi, 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???

    ReplyDelete
  30. Hello sir,

    “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.

    ReplyDelete
  31. Its an awesome tutorial for those who want to have a hang on GWT.
    Actually 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

    ReplyDelete
  32. thanks very much .the best tutorial about GWT.how to make a link in GWT

    ReplyDelete
  33. Brother, nice explanation !!!

    ReplyDelete
  34. very fine artical good and write more such importent artical

    ReplyDelete
  35. Thanks ! 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.

    ReplyDelete
  36. Your 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...

    ReplyDelete
  37. Best tutorial on GWT, ever.

    thanks!

    ReplyDelete
  38. hmm this site is really awesome and informative to me, i am also gonna share this site to my friends and buddies.

    ReplyDelete
  39. It is a fabulous site and it is very clear how to create web apps using toolkit and java servlets.

    ReplyDelete

Post Top Ad

Responsive Ads Here