I start by the presentation of GWT: GWT (Google Web Toolkit) 2.4.0, is a popular framework available as open source since the end of 2007, which addresses the following problematic topics:
- the support of different browsers that do not support all the JavaScript in the same way, especially concerning the implementation of AJAX applications);
- the maintenance and evolution of applications with Web GUI is continually enriched;
- the requirement of a solid grasp of Web technologies and languages JavaScript, CSS and HTML of Java developers who know often the basics of these languages;
- the difficulties of development and debugging applications easly written in the interpreted and untyped Javascript;
- the time loading of JavaScript code used to rich Web application;
GWT proposes an original approach for writing rich web applications in Java, a dedicated compiler taking care of convert them into JavaScript.
Principles of functioning
The GWT framework has chosen to write the treatment of rich Web applications running in browsers not JavaScript, but in Java. For that, the GWT framework provides a dedicated compiler to transform this code in JavaScript. Therefore, IDE like Eclipse can be used for development aid such as completion and debugging. So, the goal is running the Java code in browsers.
One big advantage of the tool that GWT is Java to JavaScript compiler provides native JavaScript optimizations generated. This promotes a more robust code, optimized for the browser used.
These optimizations are:
- Compressing with GZip files exchanged.
- Reduction in the size of JavaScript files through variable names and JavaScript functions shortcuts.
- Loading mechanism in the background scripts based on a hidden iframe.
- Using caching browsers.
- Loading the browser only functions needed for its treatment.
- Generation at compile JavaScript code optimized for each browser. Once loaded, the browser keeps cached the appropriate code.
More, the GWT framework provides two modes of execution depending on the context:
- Hosted (or managed, development): the application is run as Java bytecode and allows to debug the Java code of your application directly via the standard Java debugger. This mode is used exclusively within the development environment.
- Web: the application is translated into HTML and Javascript code and can be deployed to a webserver. And, the browser simply reads the code generated by the GWT compiler and interpreter naturally.
Configuring GWT
GWT is based on the module concept to modularize the different treatments which are internal to an application or if they relate to libraries GWT. To this end, GWT imposes a strict structure of packages and location of certain entities.
A GWT module is composed of the following:
- Java classes on the Web GUI and the data objects and interfaces of remote services used. These classes are converted to JavaScript code during the compilation phase described above, and this code is run in a browser Web. Each module can defines at least one Entry point classes which is the starting point for a GWT application (similar to the main method in a standard Java program). An entry point is a Java class which implements the interface “com.google.gwt.core.client.EntryPoint” and must define the method onModuleLoad().
- Java classes for Implementing remote services used. These classes are not compiled in JavaScript as they are executed at an application server. They have a responsibility to respond to AJAX requests from GWT.
- Web resource (HTML or JSP page) called “host page” which provides the entry point of the application and related resources styles and additional style and JavaScript files. This resource executes the code for a GWT web application and can define “div” containers to which the GWT application can assign GWT UI components which are simply assigned to the body tag of the HTML page. More, the look and feel of a GWT application can be customized via style (CSS) files. So, a GWT widget can be given in a HTML “div” container and can be individually styled by CSS via the use of the Java method setStyle(String s).
- Module configuration file to define the GWT used (the class of the entry point), for example, for a module “mymodulename” is described by a configuration file “mymodulename.gwt.xml”.
To implement these elements, GWT imposes two concepts:
- “project” corresponding to all the resources that will produce a war
- “application” also called “EntryPoint” or “module” corresponding to an URL and thus an HTML page. This page will load the scripts Javascript that will shape the windows and panels. It may seem to chain different pages whereas it is technically the same HTML page generated by GWT.
The module configuration file is an XML file with the following structure:
<module> <!-- Specification of the elements used (and GWT libraries) --> <inherits name="..."/>← (1) <inherits name="..."/>← (1) <!-- Specifying elements CSS and JavaScript --> <script src="..."/>← (2) <stylesheet src="..."/>← (2) <!-- Servlet specification for testing --> <servlet path="..." class="..."/>← (3) <!-- Specifying the entry point --> <entry-point class="..."/>← (4) <!-- Properties --> <extend-property name="locale" values="fr"/> <extend-property name="locale" values="en"/> </module>
First, the GWT and external modules must be specified through the Inherits tag (1). The values must match the IDs of modules related to the structure described above. Here is a sample configuration:
<inherits name="com.google.gwt.user.User"/> <inherits name="com.gwtext.GwtExt"/>
The tags script and stylesheet (2) allow to define and JavaScript CSS to use in the GWT module. References can match to both files in the public directory of the module to remote files available on the Internet.
The servlet tag (3) specifies servlets to be used in the tests at the Hosted Mode.
The entry point of the module is specified by the tag entry-point (4), which references the class corresponding. Because this class corresponds to the Web GUI, it must be in a sub-package of client and must implement the interface EntryPoint GWT localized com.google.gwt.core.client in the package.
The following code shows an entry point class (MyGwtModule1.java) that implements the EntryPoint interface (1) and corresponding method onModuleLoad (2):
package .....web.gwt.client; (…) /** * Entry point classes define <code>onModuleLoad()</code>. */ public class MyGwtModule1 implements EntryPoint {← (1) (…) public void onModuleLoad() {← (2) // Building rich web GUI are introduced in this method (...) } }
The configuration of this class (MyGwtModule1.gwt.xml) as a class entry point of the module is illustrated in the following code:
<!-- Specify the app entry point class. --> <entry-point class='com.ho.gwt.test1.module1.client.MyGwtModule1'/>
Rich Web GUIs
Without going into all the details of the GWT framework, we present below the main graphic components.
The following tables summarize the components provided by GWT to build rich Web GUIs.
The GWT framework allows the positioning of elements providing a mechanism for merging the concepts and panel layout. The following four types of panels are available: simple, complex, and table with separation.
Component | Description |
---|---|
Button | HTML button |
Grid, HTMLTable, FlexTable | Allows the implementation of different types of tables. |
HTML | Can place the HTML code |
Hyperlink | Hyperlink |
Image and ImageBundle | Can insert an image portion or an entire image. The second component is used to group multiple images to minimize the exchange network. |
Label | Display area |
ListBox | Allows the implementation of value lists. |
MenuBar | Menu bar |
SuggestBox | Area with proposed content on the fly |
TextBox | Input area |
Tree | Allows the implementation of trees. |
Component | Description |
---|---|
AbsolutePanel | Allows absolute positioning of components. |
DisclosurePanel | A notch can unmask the elements. |
DockPanel | To arrange the components according to sides (north, west, central, east and south). |
FlowPanel and StackPanel | Respectively allow positioning of components based on the concept of HTML flow and set menus. |
FormPanel | Used to position form elements and interact with the server to manipulate the data. |
HorizontalPanel and VerticalPanel | Aligns components horizontally or vertically. |
HTMLPanel | Can integrate into applications GWT pages from external sites. |
PopupPanel and DialogPanel | Used to implement each of context menus and windows within the browser. |
SplitPanel | Sets the resizable areas. |
TabPanel | Allows to implement tabs.Clicking the tab button to view its contents. |
The panels are primarily components corresponding to components and containers can be combined to achieve advanced positioning components.
The following code illustrates an example of structure’s creation of the application in GWT on the graphic components and panels described in above tables:
public void onModuleLoad() { (…) final Button sendButton = new Button("Send"); final TextBox nameField = new TextBox(); nameField.setText("GWT User"); final Label errorLabel = new Label(); // We can add style names to widgets sendButton.addStyleName("sendButton"); // Add the nameField and sendButton to the RootPanel // Use RootPanel.get() to get the entire body element RootPanel.get("nameFieldContainer").add(nameField); RootPanel.get("sendButtonContainer").add(sendButton); RootPanel.get("errorLabelContainer").add(errorLabel); // Focus the cursor on the name field when the app loads nameField.setFocus(true); nameField.selectAll(); // Create the popup dialog box final DialogBox dialogBox = new DialogBox(); dialogBox.setText("Remote Procedure Call"); dialogBox.setAnimationEnabled(true); final Button closeButton = new Button("Close"); // We can set the id of a widget by accessing its Element closeButton.getElement().setId("closeButton"); final Label textToServerLabel = new Label(); final HTML serverResponseLabel = new HTML(); VerticalPanel dialogVPanel = new VerticalPanel(); dialogVPanel.addStyleName("dialogVPanel"); dialogVPanel.add(new HTML("<b>Sending name to the server:</b>")); dialogVPanel.add(textToServerLabel); dialogVPanel.add(new HTML("<br><b>Server replies:</b>")); dialogVPanel.add(serverResponseLabel); dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT); dialogVPanel.add(closeButton); dialogBox.setWidget(dialogVPanel); (…) // Add a handler to send the name to the server MyHandler handler = new MyHandler(); sendButton.addClickHandler(handler); nameField.addKeyUpHandler(handler); }
Remote Calls
GWT includes a mechanism to make AJAX calls to exchange data between the GUI and Web server treatments. At the client side, the mechanism maps the corresponding operation is based on JavaScript and callback methods. GWT provides its own remote procedure calls (RPC’s) which allow the GWT client to call server-side methods.
The implementation of GWT RPC is based on the servlet technology. GWT allows Java objects to be sent directly between the client and the server; which are automatically serialized by the framework. With GWT RPC the communication is almost transparent for the GWT client and always asynchronous so that the client does not block during the communication.
To create a GWT service it is necessary to define the following entities:
- An interface which extends RemoteService that lists the service methods.
- An asynchronous interface to your service which will be used in the client code. This is the AJAX GWT interfacee corresponding to the previous interface, but the mechanisms of integrating AJAX callback. It also specifies the methods used so distant and asynchronous.
- An implementation – implements the interface and extends the RemoteServiceServlet.
Interfaces above must be available at the client side of GWT and be located in a sub-package the client package. The implementation is executed next server, it must be present in a sub-package package server.
GWT requires service interfaces interface corresponding to expand its RemoteService Package com.google.gwt.user.client.rpc. This allows you to specify that this is an interface for a service accessible via GWT.
The following code illustrates the implementation of an interface like this:
/** * The client side stub for the RPC service. * * An interface which extends RemoteService that lists the service methods. */ @RemoteServiceRelativePath("javaGwtTest1RemoteService") // javaGwtTest1RemoteService used in web.xml "<url-pattern>/myGwtModule1/javaGwtTest1RemoteService</url-pattern>" public interface JavaGwtTest1Service extends RemoteService { String getMessage4Name(String name) throws IllegalArgumentException; }
The server implementation must implement this interface and base class extend RemoteServiceServlet Package com.google.gwt.user.server.rpc. This class allows you to specify the service as a servlet, this class must be defined in web.xml.
The following code provides an example implementation of the previous interface:
/** * The server side implementation of the RPC service. * * An implementation - implements the interface and extends the RemoteServiceServlet. */ @SuppressWarnings("serial") public class JavaGwtTest1ServiceImpl extends RemoteServiceServlet implements JavaGwtTest1Service { public String getMessage4Name(String input) throws IllegalArgumentException { // Verify that the input is valid. if (!FieldVerifier.isValidName(input)) { // If the input is not valid, throw an IllegalArgumentException back to the client. throw new IllegalArgumentException("Name must be at least 4 characters long"); } String serverInfo = getServletContext().getServerInfo(); String userAgent = getThreadLocalRequest().getHeader("User-Agent"); // Escape data from the client to avoid cross-site script vulnerabilities. input = escapeHtml(input); userAgent = escapeHtml(userAgent); return "Hello, " + input + "!<br><br>I am running " + serverInfo + ".<br><br>It looks like you are using:<br>" + userAgent; } (...) }
Alongside the service interface, an asynchronous interface associated should be defined. The latter contains the methods defined above by adding a parameter corresponding to the entity return, the latter corresponding to the type AsyncCallback Package com.google.gwt.user.client.rpc. It should be noted that these methods have longer back.
The interface corresponding to the previous example is described in the following code:
/** * The async counterpart of <code>JavaGwtTest1Service</code>. * * Asynchronous interface to your service which will be used in the client code */ public interface JavaGwtTest1ServiceAsync { void getMessage4Name(String input, AsyncCallback<String> callback) throws IllegalArgumentException; }
Once these entities defined, AJAX remote calls can be implemented in GWT. At this point, the key entity is the GWT class, which lets you create within the Web GUI for the client’s call the service remotely.
The following code illustrates how to create an entity calling the remote service. Using the create method offers the possibility to create this forum (1), on which the access address can be specified (2). Calling methods of service is achieved through the asynchronous interface (3) entity and a booster (4):
JavaGwtTest1ServiceAsync javaGwtTest1Service = ←(1) GWT.create(JavaGwtTest1Service.class); // Definir l’URL : elle doit appartenir au meme domaine que la page html Host ServiceDefTarget endpoint = (ServiceDefTarget) javaGwtTest1Service; // GWT.getModuleBaseURL() = http://127.0.0.1:8888/myGwtModule21/ endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() ←(2) + "javaGwtTest1RemoteService"); (…) javaGwtTest1Service.getMessage4Name(textToServer, new AsyncCallback<String>() { ←(3) /** * onFailure */ public void onFailure(Throwable caught) {←(4) // Show the RPC error message to the user dialogBox.setText("Remote Procedure Call - Failure"); serverResponseLabel.addStyleName("serverResponseLabelError"); serverResponseLabel.setHTML(SERVER_ERROR); dialogBox.center(); closeButton.setFocus(true); } /** * onSuccess */ public void onSuccess(String result) {←(4) dialogBox.setText("Remote Procedure Call"); serverResponseLabel.removeStyleName("serverResponseLabelError"); serverResponseLabel.setHTML(result); dialogBox.center(); closeButton.setFocus(true); } });
GWT user an embedded server named Jetty.
Jetty is an open-source project providing a HTTP server, HTTP client and javax.servlet container.These 100% java components are full-featured, standards based, small foot print, embeddable, asynchronous and enterprise scalable. Jetty is used in a wide variety of projects and products: embedded in phones, in tools like the the eclipse IDE, in frameworks like GWT, in application servers like Apache Geronimo and in huge clusters like Yahoo’s Hadoop cluster. Because of its small size, it perfect for providing web services once embedded in a Java application. Since 2009, development of the core is hosted by the Eclipse Foundation. It is embedded in the distribution as eclipse plugin.
GWT JavaDoc: http://google-web-toolkit.googlecode.com/svn/javadoc/2.4/overview-summary.html