天天看點

Google Web Toolkit簡介

一 GWT是什麼?

1 簡介

“The heart of GWT is a compiler that converts Java source into JavaScript, transforming your working Java application into an equivalent JavaScript application.”

  GWT是一個javascript或者說ajax的開發工具。但使用java作為開發語言。使用者編寫的java code由GWT Compiler編譯成js腳本。

這裡的java code是受限的java語言。它與java語言标準基本一緻(稍許差別),但支援的java類庫僅有java.lang, java.util。具體的差別參見文檔:GWT文檔的Develop Guide>Fundamentals >GWT Compiler。

2 開發流程

Code In java, test , debug  (hosted mode)

Compile into javascript

Run (web mode)

3 開發工具

GWT(projectCreator.cmd, applicationCreator.cmd, junitCreator.cmd, lib)

ant

eclipse

4 開發流程

使用projectCreator.cmd, applicationCreator.cmd建立一個工程,程式

project-Creator

Src

.project

.classpath

projectName.ant.xml

applicationCreator.cmd(建立用戶端類):

  appName-compile.cmd

  appName-shell.cmd

  appName.launch

  src/com/comName/projectName/client/app.java

  src/com/comName/projectName/public/app.html

src/com/comName/projectName/app.gwt.xml

二 專題

1 構造複雜頁面(參見:Develop Guide>Buiding User Interface)

  由GWT生成的工程,是為了開發采用了AJAX技術的web應用程式。他工作起來更像一個運作在浏覽器中的應用程式。網頁的界面一部份是html文檔中的靜态頁面,另一部份是由js腳本生成的。生成界面的腳本由GWT編譯器編譯java程式得到。

  在開發時,對于界面,我們要做的工作就是:編輯靜态頁面(位于src/com/comName/projectName/public中),以及開發java源程式以生成js腳本(位于src/com/comName/projectName/client中)。

  在GWT中,僅支援java.lang, java.util類庫, 不支援java.awt, javax.swing這些java界面類庫。在GWT工程的java程式中,界面的實作是通過使用GWT提供的界面類庫,(主要的類有:com.google.gwt.user.client.ui.Widget,com.google.gwt.user.client.ui.Panel)來實作的。

  下面我們通過一個例子來看看腳本生成的界面。

  在GWT開發過程中,一個application最基本的構成由一個靜态網頁和一個java源程式。Java源程式必須包含一個public void onModuleLoad()函數,這個函數是繼承自com.google.gwt.core.client.EntryPoint一個函數(但在給出的sample中有一個類沒有實作該接口);在這個函數中通過操縱com.google.gwt.user.client.ui.RootPanel來向網頁中增加界面内容。以下是一個最簡單的java源程式的構成:

package com.google.gwt.sample.hello.client;

import com.google.gwt.core.client.EntryPoint;

import com.google.gwt.user.client.Window;

import com.google.gwt.user.client.ui.Button;

import com.google.gwt.user.client.ui.ClickListener;

import com.google.gwt.user.client.ui.RootPanel;

import com.google.gwt.user.client.ui.Widget;

public class Hello implements EntryPoint {

  public void onModuleLoad() {

    Button b = new Button("Click me", new ClickListener() {

      public void onClick(Widget sender) {

        Window.alert("Hello, AJAX ");

      }

    });

    RootPanel.get().add(b);

  }

}

RootPanle.get()函數仍然傳回一個RootPanle對象,參數是一個字元串或者為空。這個參數的意義是:它對應于該application中靜态頁面中一個元素的id屬性。傳回的是給id對應元素關聯的RootPanle對象,也就是該元素對應的顯示區域。

Panel的概念和javax.swing中Panel的概念類似,Widget和javax.swing中的控件的概念類似。

一些基本的控件在GWT文檔的Develop Guide>Buiding User Interface>Widgets Gallery中有一個展示。

由js腳本生成并添加到頁面中的控件在靜态頁面的源檔案中沒有任何html代碼資訊。

2 事務處理及Layout

  與java.awt, javax.swing中事件處理機制類似,隻是現在要使用的是com.google.gwt.user.client.ui中的類庫。

3 和Servlet的資料互動(參見:Developer Guide>Remote Procedure Calls)

  運作在浏覽器中的應用程式通過Remote Service的概念和伺服器互動。

  首先在用戶端的java代碼中,先定義自己的服務接口,這個接口要繼承com.google.gwt.user.client.rpc.RemoteService接口。

 這個自動義的接口提供了可遠端調用的函數。以下是個例子:

 public interface MyService extends RemoteService {      
             public String myMethod(String s);      
 }      

 函數的參數時要傳給遠端伺服器的參數,傳回值是遠端伺服器傳回的結果。

 然後,要實作提供這個服務的Servlet。

 這個Servlet要實作先前定義的服務接口。

 而且要繼承自com.google.gwt.user.server.rpc.RemoteServiceServlet。當然RemoteServiceServlet繼承自HttpServlet。這個Servlet運作在web server上,例如tomcat。

public class MyServiceImpl extends RemoteServiceServlet implements      
    MyService {      
  public String myMethod(String s) {      
    // Do something interesting with 's' here on the server.      
    return s;      
  }      
}      

  第三,定義異步接口。

 “Ajax的核心是JavaScript對象XmlHttpRequest。該對象在Internet Explorer 5中首次引入,它是一種支援異步請求的技術。簡而言之,XmlHttpRequest使您可以使用JavaScript向伺服器提出請求并處理響應,而不 阻塞使用者。”

 GWT支援的是這種異步請求機制。要實作這種異步請求機制,就要實作異步接口。

  異步接口定義在用戶端。

 異步接口的定義規則是:不需要繼承任何接口,名字是在自定義服務接口的名字後面添加Async字尾;接口中的方法與自定義服務接口方法同名,傳回值為void,參數在自定義服務接口方法參數的基礎上增加一個com.google.gwt.user.client.rpc.AsyncCallback類型的參數。

 interface MyServiceAsync {      
        public void myMethod(String s, AsyncCallback callback);      
 }      

 第四,調用過程。

參考如下示例:

public void 調用函數() {      
  // (1) Create the client proxy. Note that although you are creating the      
  // service interface proper, you cast the result to the async version      // of the interface. The cast is always safe because the generated proxy      
  // implements the async interface automatically.      
  //      
  MyServiceAsync myService = (MyServiceAsync) GWT      
    .create(MyService.class);      
  // (2) Specify the URL at which our service implementation is running.      
  // Note that the target URL must reside on the same domain and port from      
  // which the host page was served.      
  //      
  ServiceDefTarget endpoint = (ServiceDefTarget) myService;      
  endpoint.setServiceEntryPoint("/requestPath");      
  // (3) Create an async callback to handle the result.      
  //      
  AsyncCallback callback = new AsyncCallback() {      
    public void onSuccess(Object result) {      
      // do some UI stuff to show success      
    }      
    public void onFailure(Throwable caught) {      
      // do some UI stuff to show failure      
    }      
  };      
  // (4) Make the call. Control flow will continue immediately and later      
  // 'callback' will be invoked when the RPC completes.      
  //      
  myService.myMethod (“argument”, callback);      
}      
  可以看到,遠端服務調用的過程是這樣的:      
  1 生成異步接口的對象。      
  2 定義遠端通路點。      
  3 建立AsyncCallback對象。      
  4 遠端調用。      
  實作異步接口的調用過程,不會阻塞使用者程序,會從函數中直接傳回;當使用者結果傳回時會由AsyncCallback對象對傳回結果做處理。      

4 和Structs的整合

  現在關于AJAX和Structs整合的文章在google, baidu上基本上搜尋不到。

  如果Ajax用戶端向伺服器發請求和通過浏覽器向某Servlet發請求的機制一樣,可以用一個Action來實作3中提到的Servlet。

  但伺服器結果傳回Ajax用戶端的的過程和普通Servlet響應傳回浏覽器的過程明顯不同,是以Structs的整合問題還有待進一步研究。

繼續閱讀