CSC/ECE 517 Fall 2014/ch1a 6 bn

From Expertiza_Wiki
Jump to navigation Jump to search

Google Web Toolkit

Google Web Toolkit(GWT)<ref>http://www.gwtproject.org/GWTPolicy.html</ref> is a set of tools used to develop browser based RICH Web Applications(RIA). It is a free open source web framework released in 2006 under Apache 2.0 License. The focus of this toolkit is to provide great user experience by bringing the features and feel similar to that of a desktop application to the browser based web applications. GWT as a framework can be used to build large scale and high performance easy-to-maintain web appliations. GWT is used by many products at Google, including AdWords, AdSense, Flights, Hotel Finder, Offers, Wallet, Blogger, Maps.

The latest Version of GWT (GWT 2.6.1) was released on May 10, 2014.

GWT Features

  1. Backend Language Support: Developers can use the language of their choice for developing the back-end code.
  2. XHR Handling: GWT handles all the XHR calls for the developers irrespective of the method of communication(JSON, XML, or GWT's optimized Remote Procedure Call (RPC) system)
  3. Dynamic Optimization: GWT creates a separate compiled version of your application that is optimized for a particular user's environment.
  4. Re-usability of code: GWT supports packaging of the user generated UI components. These packages can be loaded into the other projects facilitating the reuse of UI components.
  5. Support for Browser History: GWT adds state to the browser's back button history making the use of browsers "Back" button with the application easy.
  6. Internationalization: GWT provides tools to create efficient internationalized applications and libraries, including bi-directionality.
  7. Testing using JUnit: GWT supports testing of the code using JUnit in debugger, browser and even with asynchronous RPCs direct integration with JUnit lets us use unit test both in a debugger and in a browser and you can even unit test asynchronous RPCs.
  8. Native Javascript Support: GWT supports and allows for embedding JavaScript within Java enabling the integration and use of pre-existing Javascript libraries.

Contents of the Toolkit

The Toolkit consists of a software development kit (GWT SDK) and an eclipse Plugin (Plugin for Eclipse).<ref>http://www.gwtproject.org/overview.html</ref>

GWT SDK

GWT SDK contains the Java API libraries, compiler, and development server. It lets you write client-side applications in Java and deploy them as JavaScript.<ref>http://www.tutorialspoint.com/gwt/index.htm</ref><ref>GWT in Action, by Robert Hanning & Adam Tacy,Manning, 2007</ref> The three major components of the SDK are:

GWT Java to JavaScript compiler

This is the most important part of GWT which makes it a powerful tool for building RIAs. The GWT compiler is used to translate all the application code written in Java into JavaScript.It also supports mixing of Java code with existing JavaScript code using JavaScript Native Interface (JSNI), which allows embedding of JavaScript code within Java classes in order to facilitate Java-to-JavaScript communication. An example of embedded javascript in java is shown below.

private native void nativeMethod()
/*-{
     $wnd.jsFunction = function(x) {
       alert(x);
     };
     alert("hello");
}-*/;

One key feature of the GWT compiler is that it generates multiple output JavaScript files from the input code, one per each browser to ensure cross browser compatibility of the application. The browsers currently supported by the compiler include

Firefox
Internet Explorer 8, 9, 10, 11
Safari 5, 6
Chromium and Google Chrome
Opera latest version
Compiler Modes

The compiler has three style modes that determine what the resulting Java-Script looks like. The default style is obfuscate, which makes the JavaScript look like alphabet soup. Everything is compressed and nearly impossible to decipher.An example of the obfuscated code is given below

function x(){return this.y + '#' + this.b();}

The second style is pretty which generates readable JavaScript as shown below.

function _toString(){
  return this._typeName + '#' + this._length();
}

The third style is detailed, which produces JavaScript code that looks like the pretty style with the addition of the full class name as part of the JavaScript method name. An Example would look like

function java_lang_Object_toString__(){
return this.java_lang_Object_typeName + '#' + this.length__();
}

Generally Obfuscate is used for production as it is the most optimized and compressed version of the output code and would result in faster pages. Using Obfuscate also provides a certain amount of security to the output code and can prevent code theft by making it difficult to read the output. Pretty and detailed modes are used mainly in development to aid in debugging.

JRE Emulation library

Google Web Toolkit includes a library that emulates a subset of the Java runtime library. The list includes java.lang, java.lang.annotation, java.math, java.io, java.sql, java.util and java.util.logging.

GWT UI building library

This part of GWT consists of many subparts which includes the actual UI components, RPC support, History management. GWT ships with a large set of widgets and panels for laying out UI.

Plugin for Eclipse

Plugin for Eclipse provides IDE support for GWT and App Engine web projects.

GWT Web Development Modes

GWT supports two different modes for developing Web Applications.<ref>http://en.wikipedia.org/wiki/Google_Web_Toolkit</ref>

  • Development mode: The Application is run on the local system as bytecode in the Java Virtual Machine(JVM). This mode supports hotswapping of the code, real time debugging and is typically used for development.
  • Production mode: The application is run as pure JavaScript and HTML, compiled from the Java source. This mode is typically used for deployment.

GWT Web Development Process Flowchart

Contents of GWT Application

Every GWT application contains the following four parts <ref>http://www.tutorialspoint.com/gwt/gwt_applications.htm</ref>

Module descriptors

In GWT, applications are segregated into modules. A GWT "module" is simply an encapsulation of functionality. A module is defined by an XML descriptor file ending with the extension ".gwt.xml", and the name of that file determines the name of the module. This xml file is known as module descriptor.

Typically module descriptors contain the following

  1. Inherited modules (A module can inherit the existing modules)
  2. an entry point application class name; these are optional, although any module referred to in HTML must have at least one entry-point class specified
  3. source path entries
  4. public path entries

Public resources

These are all files referenced by your GWT module, such as Host HTML page, CSS or images. The location of these resources can be configured using <public path="path" /> element in module descriptor file. By default, it is the public subdirectory underneath where the Module XML File is stored.

Client Side Code

This is the actual Java code written implementing the business logic of the application and that the GWT compiler translates into JavaScript, which will eventually run inside the browser. The location of these resources can be configured using

element in module configuration file.

Server Side Code

This is the server side part of your application and its very much optional. If you are not doing any backend processing with-in your application then you do not need this part, but if there is some processing required at backend and your client-side application interact with the server then you will have to develop these components.

Sample Application in GWT

For this sample GWT application we will be creating a module with one entry point and a host html page.

An entry point is the starting point for a GWT module, similar to the main method in a standard Java program. We define the code for Entry point through java classes and these java classes must implement com.google.gwt.core.client.EntryPoint and define method onModuleLoad().

In order to run a gwt module, it must be loaded from a web page of some sort. Any HTML page can include a GWT application via a SCRIPTtag. This HTML page is referred to as Host page from the GWT application's point of view

Creating GWT entry point

Define the following Java class "HelloGwt" which implements EntryPoint interface.<ref>http://www.vogella.com/tutorials/GWT/article.html#firstgwt_entrypoint</ref>

 public class HelloGwt implements com.google.gwt.core.client.EntryPoint {
   public void onModuleLoad() {
      Label label = new Label("Hello GWT !!!");
      Button button = new Button("Say something");
      button.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        Window.alert("Hello, again");
      }
    });
   RootPanel.get().add(label);
   RootPanel.get().add(button);
  }
 }

Creating Module Descriptor

Create the file "helloworld.gwt.xml" like as follows.

 <xml version="1.0" encoding="UTF-8"?>
 <module rename-to='helloworld'>
 <inherits name='com.google.gwt.user.User'/>
 <inherits name='com.google.gwt.user.theme.standard.Standard'/>
 <entry-point class='HelloGwt'/>
 </module>

Creating HTML Host Page

 <html>
 <head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8">
   <link type="text/css" rel="stylesheet" href="helloworld.css">
   <title>My First GWT applicaton</title>
   <script type="text/javascript" language="javascript" src="helloworld/ helloworld.nocache.js"></script>
 </head>
 </html>

Modify Web.xml

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE web-app
   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd">
  <web-app>
  <welcome-file-list>
  <welcome-file>helloworld.html</welcome-file>
  </welcome-file-list>
  </web-app> 

Running the application

To run the application in development mode in GWT IDE, you can right-click the project and select Run As -> "Web application".

Deploying the application

There are three different ways to deploy a GWT Web Application.<ref> http://www.gwtproject.org/doc/latest/DevGuideDeploying.html#DevGuideDeployingAppEngine </ref>

Deploying on a web server

To deploy a GWT application to a web server just copy the generated GWT application files after compilation and host them on the web server. The next step is to setup the server side code. This can take on a number of different forms: communicating through JSONP and working with JSON data, server-side scripts that receive and parse HTTP requests sent through the GWT RequestBuilder, or GWT RPC depending on the XHR mechanism used.

Important points to ensure proper deployment:

  • The host HTML page can actually reside anywhere on your web server.
  • The bootstrap script can also reside anywhere on your web server.
  • The GWT application files must reside in the same directory as the bootstrap script, since the script looks for the application files relative to its own location.
  • The host HTML page must reference the bootstrap script in its appropriate location on the web server.
  • Any public resources can also be placed anywhere on the web server, but these should ideally mirror the resources' path relative to the war folder during development. Otherwise, references to these resources might not hold when deployed (e,g, an Image widget referencing some .png file).


Deploying on a servlet container using RPC

Deploying a GWT application on a servlet container is an easy process. GWT compiler generates output in a directory structure that is already compliant to the Servlet 2.5 API specification. This makes it possible to deploy your application from the output directory itself.

Deploying on Google App Engine

To Deploy the application on Google App Engine, compile the application with the GWT compiler to generate the application files in the standard war directory structure, then upload and deploy your application using the appcfg utility.

If webAppCreator was used to create your project, the application can be compiled with:

ant build

and then deployed by invoking the appcfg utility with the update option:

<appengine_home_dir>/appcfg.sh update war

The appengine-web.xml file has to properly configured beforehand, and you should have a Google account to deploy it on the App Engine.

GWT RPC communication

A GWT based application generally consists of both client side code and server side code. Client side code runs in browser and server side code runs in web server. In order to access or manipulate data , Client side code has to make an HTTP request accross the network . RPC, Remote Procedure Call is the mechansim used by GWT through which client code can invoke the server side methods. The implementation of GWT RPC is based on the servlet technology. The server side servlet is usually referred to as a "service".and the remote procedure call is referred to as "invoking a service. <ref>http://www.tutorialspoint.com/gwt/gwt_rpc_communication.htm</ref>

GWT RPC Components

Following are the three components used in GWT RPC communication mechanism

  1. A remote service (server-side servlet) that runs on the server.
  2. Client code to invoke that service.
  3. Java data objects which will be passed between client and server.

GWT client and server both serialize and deserialize data automatically so developers are not required to serialize/deserialize objects and data objects can travel over HTTP.

History Management

In GWT as we are making rpc calls , there will be problem with the browser history. In static website, as each click leads to another page , the browser would be able to maintain the history of pages visited so far and when we click on back or forward button it directs us back to the previous page or later page respectively. Unlike static websites, GWT applications won’t redirect us to new pages and data is fetched through rpc calls and is refreshed in the same page itself. So browser will not have the scope to maintain history.

GWT provides a mechanism through which activate browser history. For each page that is to be navigable in the history, the application would generate a unique history token. A token is simply a string that the application can parse to return to a particular state. This token will be saved in browser history as a URL fragment (in the location bar, after the "#"), and this fragment is passed back to the application when the user goes back or forward in history, or follows a link.<ref>http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsHistory.html</ref>

For example, a history token named "page1" would be added to a URL as follows:

    http://www.example.com/com.example.gwt.HistoryExample/HistoryExample.html#page1

When the application wants to push a placeholder onto the browser's history stack, it simply invokes History.newItem(token). When the user uses the back button, a call will be made to any object that was added as a handler with History.addValueChangeHandler(). It is up to the application to restore the state according to the value of the new token.

To use GWT History support, you must first embed an iframe into your host HTML page.

 <iframe src="javascript:"
         id="__gwt_historyFrame"
         style="position:absolute;width:0;height:0;border:0"></iframe>

And in EntryPoint class add History.newItem(token) and History.addValueChangeHandler() invocations as show below.

 public class BrowserHistoryExample implements EntryPoint {
 TabPanel tabPanel;
 
 public void onModuleLoad() {
   tabPanel = new TabPanel();
   tabPanel.add(new HTML("Page 0 Content: Llamas")," Page 0 ");
   tabPanel.add(new HTML("Page 1 Content: Alpacas")," Page 1 ");
   tabPanel.add(new HTML("Page 2 Content: Camels")," Page 2 ");
   tabPanel.addSelectionHandler(new SelectionHandler<Integer>(){
     public void onSelection(SelectionEvent<Integer> event) {
       History.newItem("page" + event.getSelectedItem());
    );
   History.addValueChangeHandler(new ValueChangeHandler<String>() {
     public void onValueChange(ValueChangeEvent<String> event) {
       String historyToken = event.getValue();
       // Parse the history token
       try {
         if (historyToken.substring(0, 4).equals("page")) {
           String tabIndexToken = historyToken.substring(4, 5);
           int tabIndex = Integer.parseInt(tabIndexToken);
           // Select the specified tab panel
           tabPanel.selectTab(tabIndex);
         } else {
           tabPanel.selectTab(0);
         }
       } catch (IndexOutOfBoundsException e) {
         tabPanel.selectTab(0);
       }
     }
   });
   tabPanel.selectTab(0);
   RootPanel.get().add(tabPanel);
   }
 }

Internationalization

GWT Supports three different modes of internationalization.<ref>http://www.gwtproject.org/doc/latest/tutorial/i18n.html</ref>

Static String Internationalization: The translated strings and parameterized messages are stored in standard Java properties file. These values are then retrieved by the strongly-typed Java Interfaces based on the browsers locale.This is the simplest form of Internationalization GWT offers and carries very little overhead at runtime.

Dynamic String Internationalization: This method is used to integrate a GWT application with an existing server-side localization system.Applications using this technique look up localized strings in the module's host page; therefore, they do not need to be recompiled when adding a new locale.Dynamic string internationalization is slower than static string internationalization, but is very flexible.

Localizable Interface The most powerful technique in GWT to implement internationalization is the Localizable interface. Implementing Localizable in the application creates localized versions of custom types used in the application.

References

<references/>

Further Reading

GWT Features and Samples Showcase

Google Web Toolkit Home Page

GWT Discussion Forum

GWT Official Blog