練習 1.2:API 之間的概念差異

開始之前,您應該先完成練習 1.1:匯入資源

在這個練習中,您將學會兩種 Portlet API 之間的概念差異。

概觀

開始時,IBM Portlet API 是專為了 WebSphere Portal 第 4 版而開發的。 對於 JSR 168 Portlet API 的支援是從 WebSphere Portal 5.0.2 版開始提供。

JSR 168 Portlet API 是標準的 JavaTM Portlet 規格,它是 IBM 和 Sun 協同領導的一個小組所開發的,輸入來源是包括各主要入口網站伺服器的供應商。 它的目的是解決不同供應商的入口網站伺服器的 Portlet 相容性問題。 起始規格是在 2003 年 10 月核准。

WebSphere Portal 支援這兩種 API。它提供兩種入口網站儲存器:IBM Portlet API Portlet(以下稱為 IBM Portlet)的舊式儲存器和 JSR 168 Portlet API Portlet(以下稱為 JSR 168 Portlet)的標準儲存器。 在不同儲存器中執行的 Portlet 可以常駐於相同入口網站網頁中。

入口網站儲存器提供 Portlet 的執行時期環境。 它支援下列三個階段所組成的 Portlet 生命週期:

要求處理階段有兩個子階段:

在瞭解特定編碼差異之前,您必須先瞭解兩種 Portlet API 之間的一些基本差異。

請注意,您不需要依照下列說明來直接處理 Portlet 部署描述子的程式碼。Portlet 部署描述子編輯器會提供 portlet.xml 的圖形式使用者介面,且會自動更新程式碼。

使用 IBM Portlet API 的類別實例和資料

當開始載入 Portlet 時,會用 Web 部署描述子 (web.xml) 所提供的參數來起始設定它。 參數定義在 <servlet> 元素的 <init-param> 元素中。您可以利用 PortletConfig 物件的 getInitParameter() 方法來擷取這些參數。結果 Portlet 是一個抽象 Portlet

在使用 Portlet 之前,Portlet 部署描述子 (portlet.xml) 中的參數會先載入 PortletApplicationSettings 物件或 PortletSettings 物件。這些參數設在 <concrete-portlet-app> 元素的 <context-param> 元素及 <concrete-portlet> 元素的 <config-param> 元素中。

<concrete-portlet-app> 元素的參數適用於 Portlet 應用程式中的所有 Portlet;它們可利用 PortletSettings.getApplicationSettings() 方法來擷取。 getApplicationSettings() 方法會傳回 PortletApplicationSettings 物件,PortletApplicationSettings.getAttribute() 用來擷取個別參數。<concrete-portlet> 元素的參數適用於特定 Portlet;它們可利用 PortletSettings.getAttribute() 方法來擷取。

抽象 Portlet 加上 PortletSettings 物件資料的組合稱為具體 Portlet

將 Portlet 放在入口網站網頁時,會建立一個 PortletData 物件。具體 Portlet 加上 PortletData 物件的組合稱為具體 Portlet 實例。PortletData 物件會管理具體 Portlet 實例的持續性資料。 值是利用 PortletRequest.getData() 和 PortletData.getAttribute() 方法來擷取,利用 PortletData.setAttribute() 和 PortletData.store() 方法來儲存。 視入口網站網頁的範圍而定,資料是以使用者或群組為範圍。

具體 Portlet 實例加上 PortletSession 物件的組合稱為使用者 Portlet 實例

以下圖例顯示剛討論的物件。
IBM Portlet API 中的 Portlet 類別和資料的邏輯表示法

使用 JSR 168 Portlet API 的類別實例和資料

當使用 JSR 168 Portlet API 時,起始參數是利用 <portlet-preferences> 元素定義在 portlet.xml 中。IBM Portlet API web.xml 中的 <init-param> 元素相當於 JSR 168 Portlet API portlet.xml 中的 <init-param> 元素。

這些起始參數可以設成唯讀,但在執行時期,可以利用配置模式來加以修改。 只有管理者可以變更唯讀的起始設定參數。當在執行時期進行修改時,可以呼叫驗證器類別。驗證器類別的名稱也設在 <portlet-preferences> 元素中。PortletPreferences 物件會利用 RenderRequest.getPreferences()、PortletPreferences.getValue() 和 PortletPreferences.getValues() 方法將這些參數提供給 Portlet。<portlet-preferences> 元素相當於 <config-param> 元素加上 IBM Portlet API 中的 PortletData 物件。

PortletPreferences 物件和 Portlet 的組合稱為 Portlet 實體Portlet 視窗定義為 Portlet 模式(編輯、檢視)、Portlet 視窗狀態(正常、放到最大、縮到最小)及呈現參數的組合。 在入口網站網頁中,一個給定的 Portlet 可以有多個 Portlet 視窗,每個 Portlet 視窗都會關聯於一個特定模式、狀態和呈現參數集。

以下圖例顯示剛討論的物件。
JSR 168 API 中的 Portlet 類別和資料的邏輯表示法

Portlet 生命週期

兩種 Portlet API 所使用的生命週期都由起始設定階段、要求處理階段和消滅階段組成。 要求處理階段又分成下列子階段:動作處理和內容呈現。 請參閱要求處理,以進入要求處理階段細節的討論。 以下列出各階段所呼叫的特定方法。

IBM Portlet API 生命週期方法

init(PortletConfig)
當 Portlet 進入服務中,便會呼叫 init() 方法。PortletConfig 參數用來存取 PortletContext 物件。
initConcrete(PortletSettings)
initConcrete() 方法會利用 PortletSettings 物件來起始設定具體 Portlet。
service(PortletRequest, PortletResponse)
當 Portlet 需要呈現它的內容時,會呼叫 service() 方法。在 Portlet 的生命週期中,會呼叫 service 方法許多次。 依 Portlet 的視窗狀態而定,服務會呼叫 doView() 和 doEdit() 等方法。在進行實作的 Portlet 類別中,通常不會置換 service 方法。
destroyConcrete(PortletSettings)
當從服務中除去具體 Portlet 時,會呼叫 destroyConcrete() 方法。
destroy(PortletConfig)
當從服務中除去 Portlet 時,會呼叫 destroy() 方法,以提供清理資源的位置。

JSR 168 Portlet API 生命週期方法

init(PortletConfig)
當 Portlet 進入服務中,便會呼叫 init() 方法。PortletConfig 參數用來存取 PortletContext 物件。
render(RenderRequest, RenderResponse)
當 Portlet 需要呈現它的內容時,會呼叫 render() 方法。依 Portlet 的視窗狀態而定,它會呼叫 doEdit() 和 doView() 等方法。在進行實作的 Portlet 類別中,通常不會置換 render 方法。
processAction(ActionRequest, ActionResponse)
processAction() 方法需要 ActionRequest 和 ActionResponse 物件來作為參數。
destroy()
當從服務中除去 Portlet 時,會呼叫 destroy() 方法,以提供清理資源的位置。

要求處理

這兩種 Portlet API 都使用兩段式要求處理。 動作(或事件)會先處理,之後,再呼叫呈現階段。 在 IBM Portlet API 中,動作階段是利用 actionPerformed() 方法來呼叫,呈現階段是利用 service() 方法來呼叫。 在 JSR 168 Portlet API 中,這些階段是利用 processAction() 和 render() 方法來呼叫。

這兩種 API 之間有一項巨大差異:JSP Portlet API 在動作和呈現階段中使用不同的要求和回應物件,IBM Portlet API 的兩個階段則使用相同的物件。當使用 IBM Portlet API 時,您可以在事件處理期間設定要求和回應物件的屬性,在呈現階段期間擷取值。 當使用 JSP Portlet API 時,您可以利用階段作業物件或呈現參數來傳遞屬性值。

另一項差異是 IBM Portlet API 的 actionPerformed() 方法是透過它的 ActionEvent 參數而得以存取 PortletRequest 物件。JSR 168 Portlet API 的 processAction() 方法有 ActionRequest 和 ActionResponse 參數,它們實作 PortletRequest 和 PortletResponse 介面。

現在您已準備好開始進行練習 1.3:比較 JavaTM 類別的差異

讀者意見
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.