1.6 版多了什麼新東西?

(本文沒有翻譯更新步驟)

GWT 1.6 包含了下列幾個內容:

  • 可以直接輸出成 WAR 檔
  • 更快的 compile 速度
  • 新的 widget
  • 更新、加強版的 event handling
  • 族繁不及備載...
另外,GWT 1.6 也修正了許多在 issue tracker 上頭的 bug。如果你還在用 GWT 1.5 版的話,更著下列的步驟就可以升級到 1.6 版啦...

新的內容

新的 Project 結構

GWT 1.6 版一個很大的改變就是 project 結構。舊的輸出格式被換成標準的 Java web app「expanded war」格式,且預設的實際路徑名稱就是「/war」。請注意,war 這個目錄並不只是 compiler 的 output 目錄,裡頭也包含手動撰寫的靜態網頁(或是其他 resource)是你想要跟 GWT module 放在一起的。也請注意到,「GWTShell」跟「GWTCompiler」會是留有它們作用,不過它們在新版當中被宣告拋棄了,取代的是新的 Hosted Mode 跟 Compiler 工具來產生 war 的輸出。當 1.6 版正式釋出,我們會鼓勵現有的 project 升級成新的目錄格式,並且用新的工具來享受新版本的好處、以及對於新版 GWT 的整合性。

在 GWT 發佈的檔案中提供了一個範例 project,裡頭有新版正確的 project 設定。如果要知道新版 project 格式更多細節,請看這裡

還有幾個重要的改變:

  • 有 server 端程式碼(GWT RPC)需要設定 /war/WEB-INF/web.xml。這個檔案必須定義、發佈所有跟這個 web application 有關的 servlet。另外,server 端需要的 library 也必須放在 /war/WEB-INF/lib 下。例如,所有的 GWT RPC 都需要在這個目錄下有 gwt-servlet.jar 這個檔案。
  • HTML 網頁也不再放在 GWT module 中的 public 路徑下。我們反而建議開發者利用標準 web app 的行為,直覺地將你的靜態網頁放置在 war 目錄下。舉例來說,如果你希望在根目錄的 JSP 網頁載入一個 GWT module,讓這些手寫的靜態檔案跟 GWT compiler 產生出來的檔案分離,之後再把他們擺在 module 指定的子目錄當中。所有希望內含有 GWT module 的網頁都可以用指定該 module 子目錄、由 GWT 產生出來的 <module>.nocache.js 。1.6 版之後,我們會建議只有 module 指定的 resource 要直接放在 GWT 程式碼的目錄當中,例如 widget 需要的圖檔,就仍然留在 public 這個目錄下。
  • 當你需要從 module 的 public 路徑當中載入 resource,請務必使用 GWT.getModuleBaseURL() 所產生出來的絕對路徑。例如 GWT.getModuleBaseURL() + "dir/file.ext"。這個建議並沒有改變,只是過去對於這點比較草率,因為網頁跟 GWT module 通常會放在相同的目錄下,所以就算用相對路徑也都能運作正常。現在 GWT module 放在一個子目錄,你必須要用 GWT.getModuleBaseURL() 才有辦法指定到 public 內的 resource。

加強 Hosted Mode

雖然 GWTShell 仍舊使用內嵌的 Tomcat server,但是新版的 HostedMode 使用的是 Jetty。另外在 Hosted mode 的視窗當中新增了一個「Restart Server」按鈕。按下這個按鈕可以重新啟動 Jetty server,讓 Java 程式碼的改變可以實際有作用,而不用整個關掉 hosted mode 再開啟。這個在修改 RPC 的 servlet、RPC 回傳的 serializable type 有改變、或是 server 跟 client 已經失去同步時候特別好用。

新的 EventHandler 系統

增加了 event handler 以換掉 Widget、History 以及很多 class 上頭使用的舊 event listener。新舊系統之間一些差異在:
  • EventHandler 的 method 永遠只有一個 parameter:widget 所觸發的 GwtEvent。例如 ClickHandler 有一個 method 是 onClick(ClickEvent)
  • 所有 GwtEvent 包含了 event 有關的附屬資訊,像是 KeyEvent 中會有被按下去 key。native event 可以存取潛在 event 物件。
  • 所有 EventHandler 只定義一個 method,所以你不需要為了滿足 interface 的規格而建立一堆空的 method。
  • 對於自己建立 Widget 的使用者來說,你不再需要手動管理 listener。每個 widget 都有 HandlerManager 來管理所擁有的 handler。對於像 ClickEvent 這種 native event,只在程式碼中呼叫 addDomHandler(),就可以註冊一個 handler、並且讓關聯的 event 與 widget 連接起來。當 native event 被偵測到,handler 就會自動呼叫。對於像 SelectionEvent 這種 logical event,呼叫 addHandler() 並且用 fireEvent() 來觸發。
你可以在更新版的 GWT widget 和示範程式當中找到許多 EventHandler 的範例,在使用新版 webAppCreator 工具產生的 project 也有。

建立、驅動 native event

你現在可以對幾乎所有的 element 驅動一個 native event。用 Document.createEvent() 建立一個新的 native event,然後用 Element.dispatchEvent() 指派給特定的 element。這些 method 讓你可以擴展你的 test coverage,這在之前是辦不到的。

新的 Widget

DatePicker Widget

新的 DatePickerDateBox widget 讓你的使用者可以從日曆上選擇日期。在展示區當中有這兩個 widget 的示範。

LazyPanel Widget

新的 LazyPanel widget 讓你可以把 application 當中的某些部份,延後到第一次存取的時候才建立起來,以增加啟動的效率。舉例來說,如果你的 application 很少會用到「Help」的部份,你就可以把它放進 LazyPanel 當中,然後只有在使用者要存取它的時候才建立使用者介面。使用 LazyPanel 的方法就是繼承它,然後 override createWidget() 這個 abstract method。createWidget() 會在你對 LazyPanel 呼叫 setVisible() 時被呼叫到。

錯誤修正

GWT 1.6 包含了一堆的錯誤的修正(也包含了一些沒寫在「新的內容」章節中的改進),包括了:
  • Issue 1032:影響 Mavin plugin 的 class 載入錯誤。
  • Issue 2906SortedSet 現在是 serializable
  • Issue 779:GWT 現在用 EMMA 以支援 unit test 的 code coverage 計算。
  • Issue 2223@Override 現在可以在 interface 的 implement method 上頭使用,讓 GWT 在 Java 6 SDK 上使用得更順暢。
想要瞭解更多細節,可以到 GWT issue tracker 的 1.6 中被滿足的 Issue 完整清單查看。