國內第一本基于GWT 2.0的經(jīng)典著(zhù)作,4大專(zhuān)業(yè)社區聯(lián)袂推薦,權威性毋庸置疑!
本書(shū)內容全面,不僅詳細介紹了GWT的主要模塊和控件、GWT與JavaScript對象的交互、在GWT中使用XML、開(kāi)發(fā)自定義GWT控件、GWT-RPC和Ext GWT等必備的基礎知識,而且還深入講解了GWT與Flex整合、圖片緩存、本地化、GWT動(dòng)畫(huà)、歷史管理、延時(shí)/等待/分片執行等高級知識;本書(shū)注重實(shí)戰,所有知識點(diǎn)都配有精心設計的范例,尤為值得一提的是,還以迭代的方式重現了經(jīng)典的俄羅斯方塊游戲和一個(gè)完整的報銷(xiāo)審批系統的開(kāi)發(fā)全過(guò)程,既可以以它們?yōu)榉独M(jìn)行實(shí)戰演練,又可以將它們直接應用到實(shí)際開(kāi)發(fā)中去。
第2章 Hello GWT
本章內容
* 在Eclipse中創(chuàng )建項目
* 運行調試項目
* JUnit測試
* 發(fā)布網(wǎng)站
* ANT發(fā)布
軟件開(kāi)發(fā)類(lèi)圖書(shū)通常會(huì )從Hello World開(kāi)始,本書(shū)也不免俗。Hello World程序簡(jiǎn)單易懂,消除讀者對技術(shù)的恐懼,而且能引領(lǐng)讀者快速上手。那么,請卷起你的袖子,讓我們立刻開(kāi)始創(chuàng )建一個(gè)Hello GWT應用吧。Hello GWT的功能很簡(jiǎn)單,通過(guò)程序在一個(gè)空白頁(yè)上動(dòng)態(tài)添加一個(gè)按鈕,單擊按鈕后彈出“Hello GWT!”對話(huà)框。
2.1 在Eclipse中創(chuàng )建項目
說(shuō)明 GWT項目可以通過(guò)命令行和Eclipse插件兩種方式創(chuàng )建。創(chuàng )建GWT項目的命令是webAppCreator。出于實(shí)用性考慮,本書(shū)不使用命令行相關(guān)工具,只在說(shuō)明部分給出操作所對應的命令。具體使用方法及參數,可以查看GWT的說(shuō)明文檔。
Eclipse插件安裝完成后,Eclipse工具條中會(huì )增加一個(gè)Google toolbar。如圖2-1所示,三個(gè)按鈕分別是“New Web Application Project”(新建Web應用項目)、“GWT Compile Project”(GWT編譯項目)、“Deploy App Engine Project”(部署AppEngine項目),其中Deploy App Engine Project是Google AppEngine的工具。

圖2-1 Eclipse中的Google toolbar
單擊“New Web Application Project”按鈕打開(kāi)“New Web Application Project”對話(huà)框。輸入項目名稱(chēng)HelloGWT,包名chapter2。這里不涉及Google AppEngine,所以取消“Use Google App Engine”前的勾選,其他保持默認值,如圖2-2所示。
單擊“Finish”按鈕創(chuàng )建項目。GWT新項目向導創(chuàng )建的默認項目對于Hello GWT這樣的示例來(lái)說(shuō)有點(diǎn)復雜。刪除文件GreetingService.java、GreetingServiceAsync.java和chapter2.server包以簡(jiǎn)化項目,如圖2-3所示。


刪除不需要的文件后,web.xml也要做相應的修改,刪除web.xml中的servlet和servlet-mapping元素,修改后的內容如代碼清單2-1所示。
代碼清單2-1 修改后的web.xml文件
1 <?xml version="1.0" encoding="utf-8"?>2 <!DOCTYPE web-app3 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"4 "http://java.sun.com/dtd/web-app_2_3.dtd">5 <web-app>6 <welcome-file-list>7 <welcome-file>HelloGWT.html</welcome-file>8 </welcome-file-list>9 </web-app>
打開(kāi)HelloGWT.html刪除所有內容。先寫(xiě)一個(gè)標準的空白HTML,然后嵌入hellogwt/hellogwt.
nocache.js腳本,修改后的代碼如代碼清單2-2所示。
代碼清單2-2 HelloGWT.html源代碼
1 <html>2 <head>3 <meta http-equiv="content-type" content="text/html; charset=utf-8">4 <title>HelloGWT</title>5 <script type="text/javascript" src="hellogwt/hellogwt.nocache.js"></script>6 </head>7 <body>8 </body>9 </html>
接著(zhù)打開(kāi)HelloGWT.java,刪除所有內容后輸入代碼清單2-3中的代碼。
代碼清單2-3 HelloGWT.java源代碼
1 package chapter2.client;23 import com.google.gwt.core.client.EntryPoint;4 import com.google.gwt.event.dom.client.ClickEvent;5 import com.google.gwt.event.dom.client.ClickHandler;6 import com.google.gwt.user.client.Window;7 import com.google.gwt.user.client.ui.Button;8 import com.google.gwt.user.client.ui.RootPanel;910 public class HelloGWT implements EntryPoint {11 public void onModuleLoad() {12 Button welcomeButton = new Button("歡迎");13 welcomeButton.addClickHandler(new ClickHandler() {14 @Override15 public void onClick(ClickEvent event) {16 Window.alert("Hello GWT!");17 }18 });19 RootPanel.get().add(welcomeButton);20 }21 }
上面代碼在第12行創(chuàng )建了一個(gè)標題為“歡迎”的按鈕。第13~18行為按鈕添加了Click事件的處理程序。當用戶(hù)單擊按鈕后,會(huì )觸發(fā)第16行代碼,調用Window.alert函數在屏幕上彈出“Hello GWT!”對話(huà)框。第19行代碼會(huì )將新創(chuàng )建的按鈕添加到頁(yè)面中。
Hello GWT就這樣完成了,運行一下,看看效果如何。
2.2 運行調試項目
選中HelloGWT項目文件夾,單擊運行按鈕,如圖2-4所示。
單擊運行按鈕(Run As...)后,打開(kāi)“Run As”對話(huà)框。雙擊“Web Application”項運行項目,如圖2-5所示。


警告 GWT在項目運行時(shí)需要啟動(dòng)jetty web服務(wù)器。如果jetty的端口被占用,那么GWT項目將無(wú)法運行。如果程序無(wú)法正常運行,并且Eclipse控制臺中錯誤信息為“Port 8080 is already is use; you probably still have another session active”,表示8080端口已被其他程序占用。單擊運行按鈕邊上的向下箭頭,選擇“Run Configurations...”菜單項,打開(kāi)“Run Configurations”對話(huà)框。選擇“Web Application”下面的“HelloGWT.html”后,在右邊面板“Embedded Server”下,把“Port”設置為一個(gè)未用的端口號。
項目運行后界面出現亂碼,如圖2-6所示。
右鍵單擊HelloGWT項目文件夾選擇“Properties”菜單項。打開(kāi)“Properties for HelloGWT”對話(huà)框,在“Resource”配置項下將“Text file encoding”改為“Other:utf-8”,如圖2-7所示。單擊“OK”按鈕關(guān)閉設置項目屬性窗口。


圖2-6 界面出現亂碼 圖2-7 修改項目文件編碼格式
技巧 GWT編譯器使用utf-8編碼格式讀取源代碼文件,將項目轉變?yōu)閡tf-8編碼格式可以避免亂碼問(wèn)題。
提示 修改項目文件編碼格式后,項目文件中已存漢字全部變成亂碼,需要手工修復。打開(kāi)HelloGWT.java文件,修復第12行的亂碼。
修改后直接單擊圖2-6運行界面的“Refresh”按鈕或按F5刷新界面,中文亂碼問(wèn)題即可解決。單擊“歡迎”按鈕,彈出“Hello GWT!”消息框,如圖2-8所示。

圖2-8 Hello GWT界面
技巧 GWT項目修改源代碼后不需要重新運行項目,直接刷新頁(yè)面就能看到效果。
你可能想知道啟動(dòng)的是什么瀏覽器,這是GWT托管運行環(huán)境(GWT Hosted Web Browser)。GWT程序有兩種運行模式:普通模式和托管模式(Hosted)。很容易區分這兩種運行模式,從Eclipse中啟動(dòng)的程序,運行于托管模式下;在瀏覽器中運行的程序以普通模式運行。GWT只能在托管模式下進(jìn)行調試。
提示 GWT程序在托管模式下的運行速度明顯慢于普通模式下的運行速度,因為GWT程序在受控環(huán)境下并不會(huì )真正生成JavaScript,而是模擬運行,以便于調試器介入。
接著(zhù)試驗如何在GWT中進(jìn)行調試。GWT調試和普通Java程序調試完全一樣。我們打開(kāi)HelloGWT.java文件,在第16行設置斷點(diǎn)(Ctrl+Shift+B),然后單擊運行按鈕左邊的調試按鈕。
注意 先關(guān)閉剛才打開(kāi)的Google Web Toolkit Hosted Mode窗口,否則GWT的Web服務(wù)器端口會(huì )發(fā)生沖突,無(wú)法啟動(dòng)程序。
Hello GWT程序啟動(dòng)后,單擊“歡迎”按鈕,調試斷點(diǎn)被觸發(fā)。接著(zhù)可以進(jìn)行單步調試、查看變量等常規調試操作,如圖2-9所示。

圖2-9 調試斷點(diǎn)被觸發(fā)
在GWT 2.0中調試的方式有所不同。首先術(shù)語(yǔ)上發(fā)生了變化,在1.x版本中的“托管模式(hosted mode)”被改為“開(kāi)發(fā)模式(development mode)”,由于“托管模式”的意義讓人感到含糊不清,所以GWT開(kāi)發(fā)組選擇了有更清晰含義的“開(kāi)發(fā)模式”替代“托管模式”。與此對應,“網(wǎng)頁(yè)模式(web mode)”也被改為“生產(chǎn)模式(production mode)”。
在GWT 1.x版本中,開(kāi)發(fā)者在一個(gè)被稱(chēng)為“托管瀏覽器”中進(jìn)行代碼調試,參見(jiàn)圖2-8。在大多數情況下,托管瀏覽器工作的很不錯。不過(guò)還是存在著(zhù)一些問(wèn)題,例如你用Window.open彈出一個(gè)新的瀏覽器窗口,“托管瀏覽器”就無(wú)法很好地為你處理打開(kāi)的式樣參數。
另外一個(gè)重要的限制就是托管環(huán)境只支持某種瀏覽器,在Windows平臺下,托管環(huán)境只支持IE瀏覽器;在Linux平臺下,只支持Firefox瀏覽器;在Mac平臺下,只支持Safari瀏覽器。也就是說(shuō)如果在Windows環(huán)境中編寫(xiě)GWT程序,但是你會(huì )發(fā)現用戶(hù)在Firefox瀏覽器中運行有問(wèn)題,舊版本的GWT就無(wú)法針對這種情況進(jìn)行調試。
舊版本的GWT的托管運行環(huán)境有比較嚴重的內存泄漏,調試環(huán)境運行一段時(shí)間后開(kāi)發(fā)團隊就不得不重啟托管調試環(huán)境,這給開(kāi)發(fā)工作帶來(lái)了諸多不便。
GWT 2.0完全摒棄了托管瀏覽器的調試模式,而轉由使用瀏覽器插件進(jìn)行調試。下面我們來(lái)介紹一下這種新的調試模式。
在GWT 2.0的環(huán)境中直接單擊調試按鈕,與1.x版本的調試不同,GWT并沒(méi)有彈出任何對話(huà)框。而是在控制臺輸出了一些信息,如圖2-10所示。
這段文字的意思是GWT開(kāi)發(fā)環(huán)境所用的Web服務(wù)已經(jīng)啟動(dòng),可以通過(guò)訪(fǎng)問(wèn)下面的地址進(jìn)行調試。
http://localhost:8888/DemoGWT2.html?gwt.codesvr=192.168.1.130:3388

圖2-10 控制臺輸出
我們將這個(gè)地址復制到GWT調試器支持的瀏覽器中,目前支持的瀏覽器有IE、Firefox、Chrome和Safari。
注意 Chrome只支持4.0以后的版本。
以IE8為例,用IE8打開(kāi)該地址后,可以看到一條提示信息,如圖2-11所示。

圖2-11 提示安裝開(kāi)發(fā)插件
這段文字的意思是GWT開(kāi)發(fā)插件尚未安裝,開(kāi)發(fā)模式運行需要安裝GWT開(kāi)發(fā)插件。單擊那個(gè)大的藍色按鈕就可以下載IE版本開(kāi)發(fā)插件,也可以通過(guò)單擊下面的超鏈接選擇其他平臺和瀏覽器的開(kāi)發(fā)插件。
點(diǎn)擊按鈕下載插件,如果是Windows XP或Vista操作系統,可以直接單擊“運行”按鈕進(jìn)行安裝。如果是Windows 7,則需要下載到本地,然后以管理員模式進(jìn)行安裝,如圖2-12所示。

圖2-12 以管理員身份運行安裝
開(kāi)發(fā)插件安裝完成后再次刷新頁(yè)面就可以看到運行的結果。在運行代碼的第一行添加一個(gè)斷點(diǎn),再次刷新頁(yè)面,可以看到Eclipse命中了我們設置的斷點(diǎn)。
2.3 JUnit測試
敏捷開(kāi)發(fā)用測試驅動(dòng)開(kāi)發(fā)(TDD)進(jìn)行自動(dòng)化回歸測試和連續集成來(lái)保證項目質(zhì)量。JUnit是Java社區著(zhù)名的開(kāi)源自動(dòng)化測試軟件。GWT可以用JUnit進(jìn)行自動(dòng)化測試。
說(shuō)明 命令行下使用junitCreator為項目增加JUnit支持。
先把JUnit庫添加到HelloGWT項目中。右鍵單擊HelloGWT項目文件夾,選擇“Properties”菜單項,打開(kāi)“Properties for HelloGWT”對話(huà)框。單擊“Java Build Path”配置項,選擇“Libraries”面板,如圖2-13所示。

圖2-13 Java Build Path配置
單擊“Add Library...”按鈕,打開(kāi)“Add Library”對話(huà)框,雙擊“JUnit”后,選擇“JUnit library version”為“JUnit 4”。單擊“Finish”關(guān)閉“Add Library”對話(huà)框。添加JUnit庫完成后,單擊“OK”按鈕關(guān)閉“Properties for HelloGWT”對話(huà)框。
在項目中添加名為test的源碼文件夾,然后在這個(gè)文件夾下添加一個(gè)名稱(chēng)為chapter2.client. HelloGWTTestCase.java的文件,修改后的項目結構如圖2-14所示。

圖2-14 增加JUnit支持后的項目結構
注意 test文件夾中測試代碼的包路徑是chapter2.client,必須和被測試代碼的包路徑相同。
給HelloGWT.java添加一個(gè)可測試的方法:
1 int add(int a, int b) {2 return a + b;3 }
打開(kāi)HelloGWTTestCase.java輸入代碼清單2-4中的內容,如下所示。
代碼清單2-4 HelloGWTTestCase.java源代碼
1 package chapter2.client;23 import com.google.gwt.junit.client.GWTTestCase;45 public class HelloGWTTestCase extends GWTTestCase {67 private HelloGWT helloGWT;89 @Override10 public String getModuleName() {11 return "chapter2.HelloGWT";12 }1314 @Override15 protected void gwtSetUp() throws Exception {16 helloGWT = new HelloGWT();17 }1819 public void testAdd() {20 assertEquals(5, helloGWT.add(2, 3));21 }2223 public void testAddFail() {24 assertEquals(6, helloGWT.add(2, 3));25 }26 }
GWTTestCase派生于JUnit的TestCase。GWT使用適配器模式,從而可以使用JUnit套件對GWT的測試單元進(jìn)行測試。HelloGWTTestCase派生于GWTTestCase,測試邏輯封裝于其中。GWTTestCase的派生類(lèi)需要實(shí)現抽象函數getModuleName,getModuleName返回被測試的GWT模塊名。
剩下的工作與編寫(xiě)標準的JUnit測試用例代碼一樣。這個(gè)示例中定義了兩種測試方法:testAdd和testAddFail,測試結果是一個(gè)成功,另外一個(gè)失敗。右鍵單擊“HelloGWTTestCase.java”,選擇“Run As”→“GWT JUnit Test”菜單項執行GWT JUnit測試。測試結果和預期一致,如圖2-15所示。

圖2-15 JUnit測試結果
2.4 發(fā)布網(wǎng)站
在Eclipse中發(fā)布網(wǎng)站有以下兩種方式:
* 單擊Eclipse運行按鈕,在受控運行環(huán)境的工具條上單擊“Compile/Browse”按鈕,如圖2-8所示。等待片刻后GWT項目編譯完成,IE窗口被自動(dòng)打開(kāi),程序在IE瀏覽器中以普通模式運行。
* 單擊Google toolbar中的“GWT Compile Project”按鈕,打開(kāi)“GWT Compile”對話(huà)框,全部采用默認設置,單擊“Compile”按鈕編譯項目。
編譯結果會(huì )輸出到war輸出目錄文件夾中,將war改名后部署到j(luò )2ee服務(wù)器中,就能直接使用。我們將war目錄改名為hellogwt,復制到j(luò )etty的webapps目錄中,啟動(dòng)jetty服務(wù)器。用瀏覽器訪(fǎng)問(wèn),如圖2-16所示。

圖2-16 部署在jetty服務(wù)器上
2.5 ANT發(fā)布
2.4節提到的發(fā)布網(wǎng)站是指在集成開(kāi)發(fā)環(huán)境中發(fā)布。大型項目需要用ANT自動(dòng)構建,GWT項目使用ANT進(jìn)行構建分兩個(gè)步驟:第一步,用javac編譯項目中的服務(wù)器端代碼,將編譯結果復制到WEB-INF/classes目錄中;第二步,用GWT編譯器將GWT模塊編譯成JavaScript。
GWT用com.google.gwt.dev.Compiler進(jìn)行編譯,Compiler類(lèi)存放在gwt-dev-windows.jar中。下面給出一個(gè)編譯GWT項目的ANT模版文件,如代碼清單2-5所示。
代碼清單2-5 編譯GWT項目所使用的ANT模板文件
1 <?xml version="1.0" encoding="utf-8" ?>2 <project name="Hellogwt" default="gwtc" basedir=".">3 <property file="build.properties" />45 <target name="gwtc">6 <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">7 <classpath>8 <pathelement location="src"/>9 <pathelement location="${gwt.sdk}/gwt-user.jar"/>10 <fileset dir="${gwt.sdk}" includes="gwt-dev*.jar"/>11 </classpath>12 <jvmarg value="-Xmx256M"/>13 <arg value="${gwt.module.name}"/>14 </java>15 </target></project>
這個(gè)ANT構建配置文件,需要兩個(gè)變量參數:gwt.sdk變量值為GWT SDK的安裝路徑,gwt.module.name變量為被編譯的GWT模塊名稱(chēng)。
說(shuō)明 GWT SDK既可以從http://code.google.com/intl/zh-CN/webtoolkit/download.html下載,也可以從Eclipse的plugins目錄里面復制出來(lái)。
GWT需要有完整的源代碼才能編譯項目。引用第三方GWT庫,或者自己編寫(xiě)的GWT擴展庫時(shí),一定要把含源代碼加入到classpath中。ANT配置文件的第8行,將項目的src路徑也加入到classpath中。如果忘記把源代碼加入到classpath中,編譯程序報告錯誤:“Unable to find 'chapter2/HelloGWT.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source? ”
有了這個(gè)ANT模板,就可以把它合并到項目完整的ANT配置中,或者用AntCall調用。
2.6 小結
很多人都覺(jué)得開(kāi)發(fā)GWT應用很復雜,但是自從官方的Eclipse插件發(fā)布后,這一情況已明顯改觀(guān)。在本章中,通過(guò)簡(jiǎn)單的鼠標點(diǎn)擊,就能創(chuàng )建出一個(gè)基本的GWT應用。在下面的章節中,將帶領(lǐng)讀者進(jìn)一步了解GWT內部機制。
聯(lián)系客服