在 SpringSource dm Server 中部署 GWT 應用程式 - 第 1 部分

工程 | Ben Corrie | 2008 年 11 月 07 日 | ...

簡介

這將是一個由 3 篇部落格文章組成的系列,逐步描述如何在 SpringSource dm Server™ 中建置和部署 GWT 應用程式。這些部落格文章的重點將如下:
  1. 在 dm Server 中以 WAR 檔案形式建置和部署 GWT StockWatcher 範例應用程式,並使用 SpringSource Tool Suite 從頭開始建置。
  2. 使用 「共用程式庫」方法進行部署:如何從 WAR 中移除 GWT 相依性,並將其作為 OSGi 捆綁包部署在 dm Server 中。
  3. 使用 「共用服務」方法進行部署:我們將單個 WAR 檔案轉換為 OSGi 服務,這些服務可以由其他應用程式共用並熱交換。
值得注意的是,在這前兩篇部落格文章中,我並未使用任何 Spring Framework。Spring 和 GWT 之間的整合本身就是一個主題,我希望盡可能讓每篇部落格文章都專注於一個重點。在第三篇部落格文章中,我將展示如何使用 Spring 發佈和使用 OSGi 服務,以及如何將其與 GWT 整合。

背景

本部落格將採取實用的逐步方法,建置 此處描述的 GWT StockWatcher 範例。Google 教學課程將引導您完成從頭開始使用 RPC 建置 GWT 範例所需的步驟。在整個過程中,我將參考教學課程中的頁面,並討論各種方法的優缺點。

本部落格假設您已安裝 SpringSource Tool Suite 1.1.1 (我使用的是 Eclipse 3.4 版本)、dm Server 1.0.0GWT 1.5。它還假設您對 Java 程式設計有良好的理解,並且對 Javascript 和 Ajax 有基本的理解。

為了在示範中使用的路徑,我在以下位置建立了一個新的 Eclipse 工作區:/Users/bcorrie/gwt/workspace。我已包含您可以下載的壓縮專案,其中包含一個GWT_ROOT_INSTALL我定義的變數。若要使用我的專案,當您匯入它們時,請導覽至「偏好設定」->「Java」->「建置路徑」->「類別路徑變數」並定義您自己的GWT_ROOT_INSTALL.

步驟 1:建立新的 GWT 專案

目前建立 GWT Eclipse 專案最簡單的方法是使用 GWT 發行版本提供的命令列工具projectCreatorapplicationCreator,以及 此處描述的-eclipse參數。這些命令列工具會建立一個簡單的 Java 專案、骨架專案檔案、一個在託管模式下執行專案的執行組態,以及用於在 Eclipse 外部執行或編譯專案的腳本。

這些工具的一個限制是它們對來源程式碼的放置位置具有規範性。您的來源程式碼必須位於名為/src的專案子目錄中,您的用戶端程式碼必須位於以client結尾的套件中,而您的伺服器程式碼必須位於以server結尾的套件中。projectCreatorapplicationCreator無法設定為執行其他操作,因為這通常是GWTShellGWTCompiler期望您的程式碼所在的位置。稍後,我們將研究一些重新組織來源程式碼和調整執行組態的方法,使其更具彈性。

在命令列上建立專案後,將其匯入 STS。

使用「匯入」->「一般」->「將現有專案匯入工作區」。

步驟 2:瀏覽 Google 教學課程並開發 Java 來源程式碼

請務必繼續瀏覽 「基礎知識」,並繼續處理 「使用遠端程序呼叫」章節。關於遠端程序呼叫的章節將確保您的股票價格更新程式碼在 Web 伺服器上執行,該伺服器將每 5 秒動態更新網頁。這簡單但強大地示範了 Ajax 的功能,以及 GWT 如何在 Java 程式碼中抽象化該行為。您最終應該得到一個看起來像這樣的專案

如果您不想經歷開發範例程式碼的過程,您可以從 此處下載我的初始專案的壓縮副本。若要使用我的專案執行,您需要完成以下步驟

- 解壓縮並匯入專案 (「匯入」->「將現有專案匯入工作區」)- 定義一個GWT_ROOT_INSTALL變數,如上述背景中所述 - 修改StockWatcher GWTShell.launch包含的執行組態,或使用以下值建立一個新的執行組態

- 在 StockWatcher 專案上按一下滑鼠右鍵 ->「執行身分」->「執行組態」- 對於「主要類別」,輸入com.google.gwt.dev.GWTShell- 在「程式引數」中,輸入-out www com.google.gwt.sample.stockwatcher.StockWatcher/StockWatcher.html- 僅限 Mac OS X,在「VM 引數」中,輸入-XstartOnFirstThread- 在「類別路徑」->「使用者項目」中

- 新增gwt-dev-<os>.jar(例如gwt-dev-mac.jar)- 新增 StockWatcher 專案/src資料夾,使用「進階」->「新增資料夾」

請注意,將/src資料夾新增至類別路徑是 GWTShell 的要求,因為它需要 Java 類別路徑上的中繼資料,例如其 .xml 檔案。

步驟 3:在託管模式下執行 - 檢查它是否運作!

託管模式允許您在部署之前,以「預先編譯」的 Java 狀態執行和偵錯 GWT 應用程式。請 此處閱讀有關託管模式的資訊。重要的是要記住,StockWatcher 應用程式的用戶端類別最終將編譯為 javascript 和 html 以部署在用戶端上,而伺服器類別將作為正常的 Java 程式碼在伺服器上執行。令人困惑的是,某些用戶端程式碼既在伺服器上用作支援類別,又在用戶端上用作編譯後的 javascript。當我們稍後開始分割專案時,這將變得更清楚。

按一下選取 StockWatcher 專案的「執行」按鈕,或選擇您在步驟 2 中建立的執行組態。

另請注意,當您在託管模式下執行時,GWTShell會建立一個/www輸出資料夾到您的專案中,以及一個/tomcat資料夾來設定內嵌的 Tomcat。如果您在測試後重新整理 StockWatcher 專案,您將會看到這些資料夾。

步驟 4:建立新的動態 Web 專案

若要建立 WAR 檔案,我們需要一個動態 Web 專案... 但我們已經有一個 Java 專案!那麼,管理此需求最明智的方法是什麼?Google 建議將編譯後的程式碼產生到 Eclipse Java 專案中,然後將 GWT 編譯器和產生的 .class 檔案的輸出剪下並貼到單獨的 WAR 專案中。我的偏好是設定 GWT 編譯器以將已部署的程式碼直接建置到 WAR 專案中,並將來源程式碼分割到兩個專案中,以便用戶端程式碼位於 Java 專案中,而伺服器程式碼位於 WAR 專案中。

那麼,為什麼不直接將所有內容複製到 WAR 專案並從那裡執行所有操作呢?嗯,我認為維護兩個單獨的專案是有道理的,原因有很多:

首先,您不希望您的託管模式將其/www/tomcat資料夾產生到您的 WAR 專案中。

其次,從託管模式專案將 javascript 和 html 產生到 WAR 專案中具有保持兩個專案更乾淨和分離關注點的優點。它消除了重複產生的程式碼,這可能會導致版本控制混亂,尤其是在產生的程式碼被混淆的情況下。

第三,如步驟 1 中所述,GWTShellGWTCompiler強制要求您的來源程式碼位於名為/src的子目錄中。這限制了您的 WAR 專案與 Maven 和 Ant 等工具整合的便利性。

最後,它允許 Java 程式碼也分離,以便您不會將多餘的用戶端程式碼複製到 WAR 檔案中。

雖然這看起來像是沒有必要的額外工作,但當我們繼續使用不同的方法時,您將會看到為什麼盡早分解程式碼可以更輕鬆地將其部署為共用服務。

因此,讓我們建立一個新的動態 Web 專案,同時建立一個 dm Server 的伺服器執行個體。

如果您的工作區中尚未安裝 dm Server 執行個體,您需要按一下「目標執行階段」文字欄位旁邊的「新增」按鈕,然後選取「建立新的本機伺服器」。請注意,我也選擇了src/main/javasrc/main/webapp分別作為「Java 來源目錄」和「內容目錄」。您可以使用預設值,但建議使用這些路徑,因為它們與 Maven 等建置工具整合良好。

接下來,我們將在兩個專案之間分割 Java 程式碼

請注意,如果您只是要將 GWT 程式碼匯出為原始 WAR 檔案,則此程式碼分割不是必要的。實現這一點最簡單的方法是將您的 Java 專案建立為 WAR 專案的 Java EE 相依性,而 Eclipse 會將您的 Java 專案轉換為 JAR 檔案,並將其新增至 WAR 中的 WEB-INF/lib。但是,這種方法的問題是您將多餘的用戶端程式碼封裝到 WAR 中,並且稍後更難將您的應用程式分割為服務。

因此,我們的專案中有 3 種 Java 程式碼:僅編譯為 javascript 和 html 的程式碼、僅限伺服器端的程式碼以及同時支援這兩種用途的程式碼。將最後兩種程式碼類型移至我們的 WAR 專案是有意義的。將我們的「通用」類別 (用戶端和伺服器使用的類別) 放入單獨的套件中也是有意義的 (同樣,在部落格 3 中,這種需求的必要性將變得更加清楚),我們將其稱為com...client.api。最後,GWT 要求我們的 Async 介面與 RemoteService 介面位於同一個套件中,因此將其重構到com...client.api套件中。完成後,它應該看起來像這樣

分割程式碼所需的最後一件事是將 StockWatcherWar 專案新增至 StockWatcher 專案的建置路徑,以便它可以存取com...client.api套件中的類別 (「屬性」->「Java 建置路徑」->「專案」->「新增...」)。

如果您願意,您可以跳過所有這些艱鉅的工作,從 此處下載我的兩個完成專案的 zip 檔案,以及各種執行組態 (請參閱步驟 2 和背景以取得有關匯入和設定的說明)。如果您有一個乾淨的工作區,您需要建立一個 dm Server 執行階段的執行個體 (「新增」->「伺服器」->「SpringSource ...」),並且您可能需要在「屬性」->「目標執行階段」中為 WAR 專案選取伺服器執行階段,因為它可能與我的不符。

步驟 5:設定 GWTCompiler 以將用戶端程式碼產生到 WAR 專案中

我們需要設定 GWT 編譯器以將我們的程式碼從 StockWatcher 專案產生到 StockWatcherWar 專案中。這與在步驟 2 中設定 GWTShell 的過程幾乎相同。修改StockWatcher GWTCompiler.launch步驟 4 中的專案 zip 檔案中包含的腳本,或使用以下值建立一個新的腳本

- 在 StockWatcher 專案上按一下滑鼠右鍵 ->「執行身分」->「執行組態」並建立一個新的組態 - 對於「主要類別」,輸入com.google.gwt.dev.GWTCompiler- 在「程式引數」中,輸入-out <工作區路徑>/StockWatcherWar/src/main/webapp com.google.gwt.sample.stockwatcher.StockWatcher- 僅限 Mac OS X,在「VM 引數」中,輸入-XstartOnFirstThread- 在「類別路徑」->「使用者項目」中

- 新增gwt-dev-<os>.jar(例如gwt-dev-mac.jar)- 新增 StockWatcher 專案/src資料夾和 StockWatcherWar/src/main/java資料夾,使用「進階」->「新增資料夾」

請注意,將來源資料夾新增至類別路徑是 Google 編譯器的要求。

現在,執行您剛建立的編譯器組態,並重新整理 StockWatcherWar 專案以查看產生的檔案。您應該會看到類似這樣的內容

步驟 6:設定 WAR 專案

您會注意到,Google 編譯器將輸出產生到 2 個資料夾中,反映了 GWT 專案的名稱。編譯器假設目標資料夾將與來源資料夾相同,並且無法取消設定此設定,因此您必須將產生的檔案拖曳到src/main/webapp資料夾中,然後刪除 2 個 Google 目錄。這實際上是 Google 自己建議您 此處執行的操作。

接下來,我們需要將所需的相依性新增到我們的專案中。

- 新增 Web 模組相依性gwt-servlet.jar(「屬性」->「Java EE 模組相依性」->「新增外部 Jar」)。請注意,此模組相依於javax.servletAPI。- 根據 Google 的說明修改web.xml檔案。也值得新增StockWatcher.html<welcome-file-list>,以便它在部署時自動顯示 (儘管這在 Eclipse 中部署時並不總是有效,因為瀏覽器視窗通常在伺服器完全初始化之前開啟)。

如果您遇到問題,請查看步驟 4 中的壓縮專案。

步驟 7:在 STS 中部署到 dm Server

現在我們已經建立了閃亮的新 WAR 專案,讓我們在 STS 內將其部署到 dm Server。只需在 StockWatcherWar 專案上按一下滑鼠右鍵,然後選取「執行身分」->「在伺服器上執行」。如果歡迎頁面沒有自動顯示,請重新整理頁面或新增/StockWatcher.html到 URL 手動輸入。

在您成功執行 WAR 專案後,您可以設定託管模式以使用 dm Server 作為其伺服器,而不是其內嵌的 Tomcat。若要執行此操作,您只需修改GWTShell的執行組態,並將程式引數變更為-noserver -out www https://127.0.0.1:8080/StockWatcherWar/。這可讓您快速測試用戶端變更。伺服器端變更會自動重新部署到正在執行的伺服器。真棒!

重要的是要提及,如果您想在使用我提倡的設定下在內嵌的 Tomcat 託管模式下執行,您需要暫時取消選取 dm Server 作為 WAR 專案屬性中的目標執行階段。這是因為將 StockWatcherWar 新增到 StockWatcher 的建置路徑也會拉入 dm Server 執行階段套件 (例如javax.servlet),這會搞亂GWTShell.

的建置路徑。假設這有效,現在讓我們封裝我們的 WAR 並在工具外部部署它。

步驟 8:在 STS 外部匯出和部署

首先,我們需要將我們的專案匯出為 WAR 檔案。這是透過在 StockWatcherWar 上按一下滑鼠右鍵 ->「匯出」->「Web」->「WAR 檔案」來實現的。如果您想知道「覆寫現有檔案」核取方塊在哪裡,那是因為似乎存在一個 Eclipse 錯誤,該錯誤會隱藏它,直到您調整 WAR 匯出對話方塊的大小為止。您可以從 此處下載我匯出的 WAR (請注意,它是壓縮的)。

匯出 WAR 後,我們需要在 STS 外部啟動 dm Server。

首先,請確定 STS dm Server 已停止,否則它們會因埠而衝突。然後,在命令列上,執行 dm Server 啟動腳本。在我的情況下,這是bin/startup.sh。您可以新增-clean選項,以確保您從乾淨的設定開始。您應該會看到訊息

[2008-10-27 14:14:44.468] server-dm-10             <SPPM0002I> 伺服器已開啟,可使用 'web' 設定檔。

成功啟動後,在 Web 瀏覽器中開啟管理主控台,使用以下 URL

https://127.0.0.1:8080/admin/web/applications/list.htm

預設使用者名稱為admin,密碼為springsource。如需有關執行和設定 dm Server 的更多詳細資訊,請參閱 使用者指南

您現在應該會看到以下內容

在「應用程式位置」文字欄位中瀏覽您匯出的 WAR 檔案,然後按一下上傳。這將上傳並部署 WAR 檔案,然後該檔案應會顯示在「已部署的應用程式」中

在終端機輸出中,您應該會看到以下訊息

[2008-10-27 14:07:44.380] server-tomcat-thread-5   <SPSC1000I> 正在建立 Web 應用程式 '/StockWatcherWar'。[2008-10-27 14:07:44.396] async-delivery-thread-1  <SPSC1001I> 正在啟動 Web 應用程式 '/StockWatcherWar'。[2008-10-27 14:07:44.684] server-tomcat-thread-5   <SPDE0010I> 'StockWatcherWar.war' 版本 '0' 的部署已完成。

最後,剩下的所有工作就是按一下上面顯示的/StockWatcherWar連結,您現在正在使用您的 GWT 應用程式!

期待第 2 部分

在下一篇部落格文章中,我們將研究如何利用 dm Server 的 OSGi 功能,從 WAR 中提取我們的 GWT 相依性,並將它們轉換為可由伺服器中執行的所有 GWT 應用程式共用的捆綁包。我們還將稍微了解一下幕後情況,看看我們的 OSGi 捆綁包如何互動。

取得 Spring 電子報

隨時掌握 Spring 電子報的最新資訊

訂閱

領先一步

VMware 提供培訓和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部