一 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整合的文章在