使用 Google Web Toolkit 開發 Ajax

來源:互聯網
上載者:User

Ajax技術是當前開發web應用的非常熱門的技術,也是Web 2.0的一個重要的組成部分。然而如果用傳統的方式Javascript進行Ajax開發的話,就會使得應用程式非常難以進行調試,從而降低了生產效率。Google最近推出的GWT有望為我們解決這個難題,GWT是一個開發Ajax應用的架構,它使程式員用Java同時開發用戶端和伺服器端的代碼。GWT的編譯器會把用於開發用戶端的Java代碼轉化成Javascript和Html,而程式員不用關心這一轉換過程。這樣程式員就可以在自己喜歡的Java IDE裡面開發自己的Ajax應用程式。

本文主要從以下幾個方面進行介紹:

1、 GWT特性簡介

2、 用GWT進行UI開發

3、 用Javascript開發Ajax應用簡介

4、 用GWT進行Ajax開發

GWT特性簡介

1.動態,可重用的UI組件

GWT提供的組件庫使使用者可以很容易的開發出漂亮的UI, 每個組件對應於GWT的一個類。在本文的第二部分會比較詳細的介紹GWT對UI的支援。

2.簡單的RPC調用

使用GWT,可以方便的實現用戶端和伺服器端的通訊,特別是使得非同步通訊變的非常簡單。在本文的後面部分將對利用GWT進行RPC調用進行詳細介紹。

3.更加方便的調試

由於在開發階段不需要產生HTML截面,使用者開發的代碼實際上是在JVM上啟動並執行,這樣使用者就可以用傳統的調試Java代碼的方法對程式進行調試,從而加快了調試的速度,減少了軟體開發的時間。

4.瀏覽器安全色性

在大多數情況下,用GWT開發出來的程式會支援IE、Firefox、Mozilla、Safari和Opera,使用者在開發的時候不必擔心瀏覽器的相容性問題。而瀏覽器的相容性問題也是用直接用Javascript進行Ajax應用開發所面臨的一個另程式員棘手問題。

5.可擴充性

如果你覺得GWT提供的API不能滿足需求,你可以利用JSNI將Javascript語句直接嵌入至Java代碼中。 

用GWT進行UI開發

在本文的這一部分,我們將探討一下GWT對UI開發的支援。在GWT中,包含我們進行Web開發所需要的大部分組件,比如按紐(Button),文字框(Text box)等。圖一顯示了部分GWT所支援的UI組件。從圖片的顯示效果來看,利用GWT可以做出非常漂亮的UI。

圖一:GWT支援的部分UI組件

值得一提的是,在每個UI組件是必須放在一個稱之為面板(Panel)的控制項裡面。而面板具有不同的風格,這也決定了UI的風格。圖二顯示了GWT所支援的部分面板。

圖二:GWT支援的部分面板

在看過這些組件之後,我們接下來用一個實驗來講述怎樣把UI組件添加到頁面上。這個實驗的最終結果是一個登入框介面。

在開始我們的實驗之前,我們需要準備一下GWT環境,首先要到Google的網站上去下載一個Windows版本的GWT,目前的版本號碼是1.0.21。然後要在機器上配置好JDK環境,具體的配置方法網路上有大量文檔,這裡就不再詳細介紹。由於我們這個實驗是在Eclipse開發環境下進行的,所以你還需要一個Eclipse的環境,可以到Eclipse的官方網站下載Eclipse的開發環境。接下來我們詳細介紹實驗過程。

1. 建立Eclipse工程

我們可以利用GWT內建的一個批次檔projectCreator.cmd來建立Eclipse的工程。三所示,我們建立了一個名字為myProject的工程,存放在目前的目錄的myProject子目錄下面,關於批次檔projectCreator.cmd的詳細用法,請參見Google關於GWT的協助文檔。

圖三:用GWT建立Eclipse工程

2. 建立GWT應用程式

在建立完Eclipse工程myProject之後,我們利用GWT內建的另外一個批次檔applicationCreator.cmd來建立一個GWT應用程式。圖四顯示了建立一個GWT應用的過程。大家注意到這個批次檔接受一個名為 -eclipse 的參數,這個參數正是指定了一個Eclipse的工程,我們的例子中指定為我們剛建立好的Eclipse工程myProject。

圖四:建立GWT應用程式

3. 匯入Eclipse工程

在建立完Eclipse工程和GWT應用程式架構後,我們接著將Eclipse工程匯入到Eclipse開發環境當中以進行進一步的開發,具體的匯入處理程序不再詳細介紹。匯入後的工程結構五所示。

圖五:匯入Eclipse工程

6.添加UI組件

在匯入工程後,我們會發現工程裡面有一個名字為DemoClient的Java檔案。這個檔案是在運行applicationCreator.cmd批次檔時建立的,我們現在需要做的工作就是在這個Java檔案上加入自己需要的UI組件。我們在這個檔案中加入了五個組件,分別是:兩個Label,一個Button,一個TextBox和一個PasswordTextBox。代碼清單Listing 1中列出了本程式的所有代碼。

Listing 1:Sample GWT Application

1    package com.sample.myProject.client;2    import com.google.gwt.core.client.EntryPoint;3    import com.google.gwt.user.client.ui.Button;4    import com.google.gwt.user.client.ui.HorizontalPanel;5    import com.google.gwt.user.client.ui.Label;6    import com.google.gwt.user.client.ui.PasswordTextBox;7    import com.google.gwt.user.client.ui.RootPanel;8    import com.google.gwt.user.client.ui.TextBox;/** * This class is used to demostrate how to add widget onto the Web page */9    public class DemoClient implements EntryPoint {  /**   * This is the entry point method, when the module is load, this method   * will be automatically invoked.   */10  public void onModuleLoad() {11    Label labelName = new Label();12    Label labelPassword = new Label();    13    TextBox tbName = new TextBox();14PasswordTextBox tbPassword = new PasswordTextBox();15Button button = new Button();16    17    labelName.setText("Name:        ");18    labelPassword.setText("Password: ");19    button.setText("submit");20    21    HorizontalPanel hPanel = new HorizontalPanel();22    HorizontalPanel hPanel2 = new HorizontalPanel();23    24    hPanel.add(labelName);25    hPanel.add(tbName);26    hPanel2.add(labelPassword);27    hPanel2.add(tbPassword);    28    RootPanel.get().add(hPanel);29    RootPanel.get().add(hPanel2);30    RootPanel.get().add(button);31  }32   }

接下來我們分析一下這些程式碼,注意到類DemoClient繼承自EntryPoint,所有需要最終被翻譯成HTML頁面的類都必須繼承自EntryPoint,並且需要重寫onModuleLoad方法,這個方法會在模組被裝載的時候自動調用。因此我們也就需要把我們的添加組件的代碼放到這個函數裡面。

程式的11至15行分別建立了5個組件的執行個體。分別是兩個Label,一個Button,一個TextBox和一個PasswordTextBox。然後程式的17到19行分別設定了兩個Label組件以及一個Button組件的顯示內容。程式的21行和22行穿件兩個Panel對象,這兩個Panel對象的類型都是水平Panel對象。也就是說放在這種Panel裡面的組件是被水平排列的。程式的24行到27行分別向這兩個Panel對象中加入TextBox組件和Label組件。在程式的最後,將剛才建立好的兩個Panel對象以及一個Button對象加到最外層的Panel當中。

7.編譯應用程式

在代碼開發完成後,我們可以雙擊工程裡面的DemoClient-compile.cmd批次檔來將我們開發出來Java檔案編譯成Javascript和HTML。編譯後的檔案將存放在工程的根目錄下面的www子目錄中。

8.運行程式

編譯好程式後,我們會發現產生了一個名字為DemoClient.html的HTML檔案,雙擊這個檔案,程式的運行結果六所示:

圖六:程式運行結果

在這一部分,我們主要討論了如何將UI組件添加到Web頁面中,而這些組件如何與遠程伺服器進行非同步互動將在下面的章節中進行討論。

用Javascript開發Ajax應用

為了使使用者能更清楚地理解用GWT開發Ajax應用與用傳統的Javascript開發Ajax應用的不同,文章的這一部分將簡要介紹如何利用Javascript對象進行Ajax應用的開發。

大家都知道Ajax技術中的一個核心對象是XMLHttpRequest對象,這個對象支援非同步請求,所謂非同步請求既是當用戶端發送一個請求到伺服器的時候,用戶端不必一直等待伺服器的響應。這樣就不會造成整個頁面的重新整理,給使用者帶來更好的體驗。而當伺服器端響應返回時,用戶端利用一個Javascript函數對傳回值進行處理,以更新頁面上的部分元素的值。

由於在IE和其他瀏覽器上聲稱XMLHttpRequest對象的方法不一樣,所以我們用Javascript建立XMLHttpRequest對象的時候必須區分不同的瀏覽器。建立一個XMLHttpRequest對象的方法如清單2 中的代碼所示。

清單2:建立XMLHttpRequest對象

1    function createObject(){2     try {3  xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");4  } catch (e1) {5  try {6    xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");7  } catch (e2) {8    xmlHttpRequest = false;9  }10  }11  if (!xmlHttpRequest) {12 xmlHttpRequest = new XMLHttpRequest();13  }14  return xmlHttpRequest;      16  }

在建立好XMLHttpRequest對象之後,來看一下如何與server端進行非同步互動。清單3中列出了與伺服器段進行互動的代碼

清單3:與伺服器端進行互動

1    function ajaxSample() {2        var xmlHttpRequest = createObject();3        var url = "/sampleServlet?userName=Jason";4        xmlHttpRequest.open("GET", url, true);5        xmlHttpRequest.onreadystatechange = updatePage;6        xmlHttpRequest.send(null);7    }

這段代碼示範了如何與伺服器端進行互動的過程。程式的第2行首先獲得一個XMLHttpRequest對象,程式的第三行指定了伺服器端響應用戶端的請求的地址。程式的第4行利用XMLHttpRequest對象開啟一個串連,第一個參數指定用GET方法傳遞參數,第二個參數指定了接受請求的URL,在我們的例子中是一個Servlet,最後一個參數設定成true意味著將要發出的請求是一個非同步請求。程式的第5行指定了回呼函數,也就是當伺服器端返回結果後執行哪個Javascript函數。

這一部分對如何利用Javascript進行Ajax開發作了一個簡要的介紹,下面我們將詳細介紹如何利用GWT進行Ajax應用的開發。

用GWT進行Ajax開發

在文章的第二部分我們已經掌握了如何利用GWT建立一個工程並在工程裡添加一個GWT應用程式,同樣我們這一部分也需要建立一個GWT的工程,並添加一個GWT應用程式,由於預設建立的GWT程式不含有Server端的範例程式碼,我們必須手工加進去。我們建立好的工程GWTSample七所示。我們將要介紹的執行個體主要功能是採用非同步通訊的方式從伺服器端取出一個字串顯示在HTML頁面上。這個例子雖然簡單,但卻包含了如何利用GWT進行Ajax開發的主要流程。

圖七:GWTSample工程結構

大家注意到我們這個工程裡面有個com.sample.myProject.server包,這個包裡麵包含有運行在伺服器端的代碼。我們從用戶端發送的請求也是發送到這個包裡面的一個Servlet上去的。

為了進行非同步呼叫,在Client端必須定義一個繼承自介面RemoteService的介面,在我們的這個例子中,我們定義了介面SampleService,SampleService的代碼如清單4所示。

1    package com.sample.myProject.client;2    import com.google.gwt.user.client.rpc.RemoteService;3    public interface SampleService extends RemoteService{4    //The implementation of this method is used to return a string5    String getString();6    }

大家注意到這個介面繼承自RemoteService,並且聲明了一個方法getString();,這個方法會在伺服器端的代碼中實現。當然,大家可能現在已經意識到,這裡聲明的方法就是我們採用非同步呼叫方式所能夠調用的方法。

在聲明完這個介面之後,我們還必須聲明另外一個非同步呼叫介面,在我們的例子中是介面SampleServiceAsync,這個介面裡聲明的方法名稱必須與SampleService裡面的相同,但是多個一個類型為AsyncCallback的參數,介面SampleServiceAsync的代碼清單如清單5所示:

清單5:SampleServiceAsync代碼清單

1    package com.sample.myProject.client;2    import com.google.gwt.user.client.rpc.AsyncCallback;3    public interface SampleServiceAsync {4    void getString(AsyncCallback callback);5}

在用戶端定義完介面之後,我們必須在伺服器端實現這個介面,在我們的例子中,類SampleServiceImpl實現了介面SampleService,同時你也會注意到SampleServiceImpl也繼承了類RemoteServiceServlet,而RemoteServiceServlet是HttpServlet的一個子類,這樣我們的用戶端的請求就可以提交到Servlet SampleServiceImpl上面。類SampleServiceImpl的代碼清單如清單6所示:

清單6:SampleServiceImpl代碼清單

1    package com.sample.myProject.server;2    import com.google.gwt.user.server.rpc.RemoteServiceServlet;3    import com.sample.myProject.client.SampleService;4public class SampleServiceImpl extends RemoteServiceServlet implements 5 SampleService {6          public String getString() {7         return "This string is from server";8          }9}

最後我們來看一下類DemoClient,這個類和我們在第二部分建立的工程myProject中的類DemoClient是同一個類型的。只不過在我們這個工程中我們使用它來進行向server端的非同步呼叫。清單7列出了類DemoClient的代碼。

清單7:DemoClient代碼清單

1    package com.sample.myProject.client;2    import com.google.gwt.core.client.EntryPoint;3    import com.google.gwt.core.client.GWT;4    import com.google.gwt.user.client.rpc.AsyncCallback;5    import com.google.gwt.user.client.rpc.ServiceDefTarget;6    import com.google.gwt.user.client.ui.Button;7    import com.google.gwt.user.client.ui.ClickListener;8    import com.google.gwt.user.client.ui.Label;9    import com.google.gwt.user.client.ui.RootPanel;10   import com.google.gwt.user.client.ui.Widget;/** * This class is used to demostrate hwo to  * interact with the server client in asynchronized * way */11   public class DemoClient implements EntryPoint {12       public void onModuleLoad() {13final SampleServiceAsync sampleService = (SampleServiceAsync) 14 GWT.create(SampleService.class);15        ServiceDefTarget target = (ServiceDefTarget)sampleService;16        String staticResponseURL = GWT.getModuleBaseURL();17        staticResponseURL += "/getStringService";18        target.setServiceEntryPoint(staticResponseURL);19        20        final Label label = new Label();21        final Button button = new Button("Get String");        22        button.addClickListener(new ClickListener() {23            public void onClick(Widget sender) {24                sampleService.getString(new AsyncCallback() {25                    public void onSuccess(Object result) {26                        label.setText((String) result);27                    }28                    public void onFailure(Throwable caught) {29                        label.setText(caught.getMessage());30                    }31                });32            }33        });34        RootPanel.get("1").add(button);35        RootPanel.get("2").add(label);36    }37}

代碼的第13行得到了一個實現了介面SampleServiceAsync的類的執行個體。第15行建立了一個ServiceDefTarget對象的一個執行個體,通過這個對象可以佈建要求的目的地。程式的第18行設定了請求的目的地的URL,在我們的例子中是"/getStringService",這個URL會在web.xml檔案中被mapping到servlet SampleServiceImpl上。程式的22行到33行為我們添加的button設定了單擊響應事件。在單擊響應事件中調用sampleService的getString(AsyncCallback callback);方法。這個方法是用來進行非同步遠端程序呼叫的(RPC).並且在實現介面AsyncCallback的代碼中指定了回呼函數,當遠端程序呼叫成功後就執行onSuccess(Object result)函數,其中result中存放有從伺服器端返回的結果.。在遠程工程調用失敗後就執行onFailure(Throwable caught)函數。程式的最後把Button組件和Label組件加到panel中。

現在我們已經完成了程式的開發,圖八顯示了我們程式的運行結果,在點擊Button後,右邊回打出一句話來,重要的是這句話是以非同步方式從伺服器端取得的,不需要進行頁面的重新整理,怎麼樣,現在是不是也想用GWT進行Ajax應用開發了呢?

圖八:RPC調用樣本

總結

本文主要對用 GWT 進行 Ajax 開發進行了比較詳細的介紹,並通過與傳統的Ajax開發方式進行比較,使讀者能更清楚地理解它們之間的區別,最後我們可以看出用GWT進行Ajax開發可以使得程式員免受調試Javascript之苦,並且GWT自動處理了瀏覽器之間的相容性問題,這些都會使得開發更加容易,快捷。因此,用GWT進行Ajax開發是一種比較好的方式。希望本文能為讀者學習GWT進行Ajax的開發有所協助。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.