在工作空間中選擇 com.devworks.tutorial.po 並點擊 Add Required Bundles,隨後點擊 Validate Bundles 確認所有相依項目已正確包含。
已配置的 OSGi 框架內建 Jetty 伺服器。Jetty 是輕量級的開源 Web 伺服器與 Servlet 容器,Eclipse 在從工作區部署 RAP 應用程式時會使用它。您可以在 Arguments 分頁配置 Jetty 的啟動參數。

預設情況下,Jetty 監聽連接埠 9090。若需變更,可修改 VM 參數中的連接埠值。在 OS X 上開發時,請在 VM 參數加入 -Djava.awt.headless=true。為了保存啟動配置,請切換至 Common 分頁,將 Shared file 設為 com.devworks.tutorial.po/launch 目錄,點擊 Apply 再 Run。啟用共享檔案後,Eclipse 會在執行時保存配置。

點擊 Run 會啟動 Jetty 伺服器並連同所選 Bundle 啟動 OSGi 框架,相關活動可在 Eclipse Console 中查看。

備忘記事本應用程式現正在啟動配置指定的連接埠本地執行(本例保留預設值 9090)。請瀏覽 https://localhost:9090/rap 查看應用程式運行狀況。

由於尚未修改任何程式碼,您會發現大部分 RCP 開發知識均可直接套用至 RAP。不過,因移除 CellEditor 參考而失去了編輯任務細節的功能。
RAP 不支援單元編輯器,因此改以對話框編輯任務細節。當使用者雙擊任務或新增任務時呼叫該對話框。打開 PersonalTaskViewer.java 並修改 createTableViewer 方法:
private void createTableViewer(final Composite composite) {
tableViewer = new TableViewer(table);
tableViewer.setUseHashlookup(true);
tableViewer.setColumnProperties(columnNames);
// 啟用任務編輯:呼叫 PersonalTaskDialog
tableViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
if (tableViewer.getSelection() != null) {
PersonalTask task = (PersonalTask) ((IStructuredSelection)
tableViewer.getSelection()).getFirstElement();
openPersonalTaskDialog(composite.getShell(), task,
POUtilities.DIALOG_MODE_EDIT);
}
}
});
// 設定預設排序器
tableViewer.setSorter(new PersonalTaskSorter(PersonalTaskSorter.TASK_DESC));
}
當使用者雙擊任務,即可從選取項取得任務並傳遞給 PersonalTaskDialog(原始碼包含於教程中)。

為 Add 按鈕的點擊事件加入類似程式碼,使點擊新增時也呼叫對話框。在 PersonalTaskDialog 類中,對 OK 按鈕事件實作一個方法,更新或新增任務至 PersonalTaskModel:
public class OKSelection extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
personalTask = getModifiedTask();
if (dialogMode.equals(POUtilities.DIALOG_MODE_EDIT)) {
taskModel.taskChanged(personalTask);
} else if (dialogMode.equals(POUtilities.DIALOG_MODE_NEW)) {
taskModel.addTask(personalTask);
}
taskDialogShell.dispose();
}
}
我們新增了工具類 POUtilities,包含全域常數、影像與 SWT 置中/封裝工具,同樣包含於教程原始碼中。至此,您已擁有一個功能完整的 RAP 應用程式,幾乎完全由 RCP 程式碼構成。接下來將重構程式碼,賦予其 Web 風格的介面外觀。
僅經少量修改即完成 RCP 到 RAP 的遷移,但外觀仍不符合 Web 應用程式的預期。RAP 提供兩種自訂機制:品牌化與主題化。主題化基於 CSS 自訂外觀;品牌化則自訂瀏覽器中的應用程式專屬設定。
目前應用程式使用預設 URL https://localhost:9090/rap 啟動,瀏覽器標題也只是乏味的「RAP 啟動頁面」。

品牌化可將這些值改為更有意義的內容,並提供使用者關閉瀏覽器時的確認機制。操作步驟:
plugin.xml,切換至 Extensions 分頁。org.eclipse.rap.ui.branding。com.devworks.tutorial.po.branding(擴充點唯一 ID)taskOrganizer(使用者可透過 localhost:9090/taskOrganizer 存取)Personal Task Organizer(瀏覽器標題列/分頁顯示)icons/alt_window_16.gif(建議使用 .ico 格式以相容多數瀏覽器)Do you want to Exit Personal Task Organizer?(關閉瀏覽器或導航至其他 URL 時顯示的確認對話框)
這會在 plugin.xml 中加入以下程式碼:
<extension point="org.eclipse.rap.ui.branding">
<branding defaultEntrypointId="com.devworks.tutorial.po.rapEntrypoint"
exitConfirmation="Do you want to Exit Personal Task Organizer ?"
favicon="icons/alt_window_16.gif"
id="com.devworks.tutorial.po.branding"
servletName="taskOrganizer"
title="Personal Task Organizer">
</branding>
</extension>
儲存檔案並重新啟動應用程式。現在可透過 localhost:9090/taskOrganizer 存取,標題已更新,favicon 也可能已變更(視瀏覽器而定)。嘗試關閉瀏覽器,應會出現退出確認對話框。

主題化基於 CSS,可定義元件的顏色、字型、邊框、留白與影像。各元件自行定義可自訂的屬性,彈性各異。文件未說明各元件支援哪些屬性,需參考 RAP 原始碼(位於 https://www.eclipse.org/rap/cvs.php 的 CVS,可在 Eclipse 中作為獨立專案匯入),在 org.eclipse.rap.rwt 套件中尋找 *.theme.xml 檔案。

例如選單主題列於 Menu.theme.xml,清單列於 List.theme.xml 等。為備忘記事本主題化文字、工具列與表格:在專案根目錄建立 po_theme 目錄,其中建立 po.css 並加入:
/* Text */
Text[BORDER] {
border: 1px solid #1080ee;
}
/* Toolbar */
ToolItem:hover {
background-color: rgb(200, 200, 200);
}
/* Table */
TreeColumn:hover, TableColumn:hover {
background-color: #8cc0ea;
}
註冊此 CSS 檔:打開 plugin.xml 的 Extensions 分頁,Add 選擇 org.eclipse.rap.ui.themes。完成後設定 file 屬性指向 po_theme/po.css,name 設為 Personal Task Organizer Theme,id 設為 com.devworks.tutorial.po.theme。

接著在品牌化擴充點的 themeId 屬性中輸入主題 ID:com.devworks.tutorial.po.theme。確保 Eclipse 編譯時能找到此檔案:切換至 plugin.xml 的 Build 分頁,在 Binary Build 中勾選 po_theme。

儲存並瀏覽應用程式查看主題化結果。

透過極少的程式碼與屬性調整,應用程式已具備 Web 部署特性。但為讓程式碼在全球可用,不能仰賴 OSGi 內建的 Jetty 伺服器。下一節將示範如何打包部署至外部伺服器。
Jetty 適合開發測試,正式部署需在 Servlet 容器中運行。本節使用 Apache Tomcat(tomcat.apache.org),請確認已安裝配置妥當。
需在部署中綁定必要外掛。ServletBridge 外掛會在 Servlet 容器中啟動 OSGi 框架並支援 OSGi HTTP 服務,連接 OSGi 框架與 Servlet 容器。從 Eclipse 網站下載專案定義檔 servletbridge-anon.psf(https://www.eclipse.org/equinox/server/downloads/servletbridge-anon.psf),定義所有必要外掛。
在選單選擇 File > Import,選 Team > Team Project Set,指定下載的 .psf 檔完成匯入。這會匯入四個專案:
org.eclipse.equinox.servletbridge - 啟動框架並綁定回 Servlet 容器org.eclipse.equinox.servletbridge.http - 委派請求給 Servlet 容器提供 OSGi HttpServiceorg.eclipse.equinox.http.servlet - 提供 HttpServiceServletorg.eclipse.equinox.http.registry - 提供 Servlet、資源與 HTTP Context 擴充點javax.servlet - 標準 Servlet API 綁定版本

使用 Ant 腳本與資源範本建構應用程式。最簡單的方式是參考 org.eclipse.rap.demo.feature 的結構:

目錄結構包含:
src/org.eclipse.rap.tools/ConfigIniCreator.java - 建立 config.ini 內容deployment/rapdemo.war - 最終部署的 WAR 檔script/webappBuilder.xml - Web 應用程式建構腳本templates/WEB-INF/eclipse/configuration/config.ini - Eclipse 執行時配置檔templates/WEB-INF/eclipse/launch.initemplates/WEB-INF/web.xml將範本與腳本資料夾複製至 com.devworks.tutorial.po.feature 專案。
打開 feature.xml 加入隨功能打包的必要外掛(完整清單見原文)。接著編輯 script/webappBuilder.xml,修改 servletbridge.dir 屬性指向本地檔案系統中 ServletBridge 專案路徑(本例為 C:/temp/eclipse/workspace/org.eclipse.equinox.servletbridge),並將 webapp.name 改為功能建構後顯示的資料夾名稱。

在 Package Explorer 中右鍵 webappBuilder.xml 選擇 Run As > Ant Build。命名為 Task Organizer,在 JRE 分頁選擇 Run in the same JRE as the workspace。點擊 Run 等待建構完成,可在 Console 監控進度。

建構完成後按 F5 重新整理專案,查看建構結果目錄結構。

config.ini 包含應用程式初始化時載入的 Bundle。執行 org.eclipse.rap.demo.feature 附帶的 ConfigIniCreator.java 更新此檔:編輯檔案路徑指向外掛部署位置(本例為 C:\temp\eclipse\workspace\com.devworks.tutorial.po.feature\build\PersonalTaskOrganizer\WEB-INF\eclipse\plugins),運行類別取得輸出並複製至 config.ini。

建立 WAR 檔:在專案中選擇 WEB-INF 目錄,右鍵 Export > General > Archive File,命名為 po.war,勾選 Create only selected directories 完成匯出。

本例 Tomcat 執行於連接埠 1234(預設通常為 8080)。使用內建 Tomcat 管理器部署:瀏覽 https://localhost:1234/manager/html,在 WAR file to deploy 輸入 po.war 路徑並點擊 Deploy。部署完成後瀏覽 localhost:1234/po/taskOrganizer 運行應用程式。

現在已成功建構獨立的任務備忘記事本並部署至本地 Servlet 容器(關閉 Eclipse 仍可運行,證明其獨立性)。若要上線,只需將相同 WAR 檔移至公開可存取的 Web 伺服器。注意:為展示 Ganymede 特性,本應用程式簡化了會話間的任務持久化。同一應用程式可在 Windows、Mac OS X、Linux 及各主流瀏覽器中無縫運行,使用者無需安裝任何外掛或軟體。
Eclipse Ganymede 包含 Rich Ajax Platform (RAP),讓開發者利用既有 RCP 桌面應用程式開發技能,建構並部署擁有桌面級功能的 Rich Internet Application,採用強大的分發模型與獨立於 Web 的平台。RAP 是 RCP 子集,需單獨下載安裝為獨立目標平台,但正因如此,現有 RCP 應用程式僅需少量修改即可轉為 Web 應用程式,共用業務邏輯程式碼庫,輕鬆維護多部署環境。
透過 SWT、JFace 與 Workbench,Eclipse RAP 連結 RCP 與 Web。開發測試可使用 Equinox 內建 Jetty 伺服器;正式部署則需遵循流程建構打包為 WAR、適合部署至 Servlet 容器的獨立應用程式。
本系列第三部分將修改備忘記事本,使用 Ganymede 新增的 embedded Rich Client Platform (eRCP) 為行動裝置開發。