程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JSR 286 Portlet的新特性,第1部分: Portlet 2.0新特性介紹

JSR 286 Portlet的新特性,第1部分: Portlet 2.0新特性介紹

編輯:關於JAVA

關於本系列

本系列文章專門針對具有 JSR 168 Portlet 開發基礎,並且想了解 JSR 286 Portlet 新特性和開發流程的開發人 員。在學習完本系列後,您將了解相對於 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增強功能, 以及這些新增特性在實際開發 中的應用。

第 1 部分將簡單回顧 JSR 168 Portlet, 並列出了 JSR 286 Portlet 的新增內容。

第 2 部分和第 3 部分將 通過在 Apache Pluto 2.0 平台上開發和部署 Portlet 應用程序, 向讀者介紹 JSR 286 Portlet 新特性的使用方法。

關於本系列

本系列文章專門針對具有 JSR 168 Portlet 開發基礎,並且想了解 JSR 286 Portlet 新特性和開發流程的開發人 員。在學習完本系列後,您將了解相對於 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增強功能, 以及這些新增特性在實際開發 中的應用。

第 1 部分將簡單回顧 JSR 168 Portlet, 並列出了 JSR 286 Portlet 的新增內容。

第 2 部分和第 3 部分將 通過在 Apache Pluto 2.0 平台上開發和部署 Portlet 應用程序, 向讀者介紹 JSR 286 Portlet 新特性的使用方法。

關於本文

本文假定讀者熟知 JSR 168 Portlet,並對 J2EE 基本常識有一定了解。本文主要以理論的方式向讀者介紹 JSR 286 Portlet 的 以下新增特性:

資源服務

事件

共享呈現參數

Portlet 過濾器

Portlet 窗口

Portlet 和 JSR 168

Portlet 是部署在容器內用來生成動態內容的 Web 組件,與 servlet 類似,portlet 的整個生命周期從 init 到 destroy 的 過程都在 portlet 容器中進行。Java Portlet Specification 對 portlet API、標准化用戶數據、參數設置、portlet 請求以及響應、 部署、打包以及安全等方面都做了詳細的規定,以此來實現 portlet 之間以及 portlet 與 portlet 容器之間的交互和協作。Java Portlet Specification 1.0, 即 Java Specification Request(JSR)168 發布於 2003 年 10 月。

JSR 286 及其新特性

JSR 168 目前在業界受到廣泛支持,而且它由開放源碼支持。標准和產品的第一個版本存在一定的缺陷,僅支持最基本的用例,在 功能上有一些限制。而且 Java Portlet Specification V1.0 也存在這種情況,因此,經過三年之後,大多數支持 Java Portlet Specification V1.0 的門戶產品都提供一些附加擴展,以支持更高級的用例,這些附加的擴展造成了各個門戶產品的標准不統一,彼此間 的交互協作成了不可避免的問題。為了更好地規范 portlet 開發,以適應業界發展,並提供適應於最高級別用例的標准解決方案,從而為 這些高級功能提供互操作性,在 2005 年 11 月開始了 Java Portlet Specification V2.0(稱為 JSR 286)的開發,Java Portlet Specification V2.0 目前已經進入 Final draft 的等待審批階段,並計劃在 2008 年 3 月正式發布。JSR 286 最終草案兼容了 JSR 168 ,並完善了 JSR 168 的部分功能,並提供了諸多 JSR 168 所沒有的新特性,例如資源服務、事件、portlet 過濾器、共享呈現參數及 portlet 窗口等。與 V1.0 類似,V2.0 也將基於 J2EE 1.4,因此可讓 Portlet 使用 J2EE 1.4 增強(如 JSP 2.0)。下面是該新規范的 一些主要功能及特性:

資源服務:一種新的通過 portlet 呈現資源的方式。

事件:通過發送事件和接收事件來實現 portlet 之間的通信。

Portlet 過濾器:與 servlet 過濾器類似,根據 Portlet 請求和響應動態的呈現內容的變換。存在以下四種類型的 portlet 過濾器 :

Action 過濾器

Render 過濾器

Resource 過濾器

Event 過濾器

共享呈現參數:除了 portlet 私有的 呈現參數之外,新增了可以在 portlet 之間共享的呈現參數。

Portlet 窗口:提供 portlet 窗口 ID 供 portlet 使用。

下面我們將對 JSR 286 所提供的這些新功能及其使用逐一做詳細介紹。

資源服務

在 JSR 168 中,Portlet 服務於資源的 方法只有兩種:直接鏈接到資源,或者通過 Portlet 服務於資源。兩種方法分別適用於不同目的的需要,各有優缺點。

直接鏈接 對於所有 Portlet 狀態都相同的靜態資源非常有效,但對於其他用例效果卻不太好,因為需要考慮來自 Portlet 上下文的信息。這樣的 示例包括基於 Portlet 模式、窗口狀態、當前呈現參數或 Portlet 首選項呈現不同資源。

以一個 JSP 文件 test.jsp 為例,如 果要訪問該資源,可以直接通過超鏈接訪問該文件,如清單 1 所示:

清單 1. 直接訪問資源文件

<a  href="<c:url value="/test.jsp" />">test.jsp</a>

或者通過 Servlet 轉向,如清單 2 和清單 3 所 示:

清單 2. 直接訪問 Servlet

<a href="<c:url  value="/testServlet" />">testServlet</a>

清單 3. Servlet 對資源文件的訪問控制

public void service(ServletRequest request, ServletResponse response)
  throws  ServletException,IOException {
  ...
  在此添加訪問控制等業務邏輯代碼
  ...
   RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/jsp/test.jsp");
  rd.forward(request, response);  //或者為 rd.include(request, response);
}

從清單 1、2、3 可以看到,直接鏈接到資源這種方式,無法訪問 到相關 Portlet 的信息,包括 Portlet 模式、窗口狀態、當前呈現參數或 Portlet 首選項等。而通過 Portlet 呈現資源的優勢是可以 通過門戶訪問資源,因此可以通過控制門戶訪問而對資源提供保護。但是,這也帶來了額外的門戶請求開銷,加重了門戶服務器的負載。

為了更好的解決這兩種方法的局限性,JSR 286 采用了一種新的資源服務方式 —— Portlet 資源服務。即 JSR 286 引入 了一個新的具有 serveResource 方法的可選生命周期接口 ResourceServingPortlet ,該接口可以由 ResourceURL 觸發,Portlet 可以 通過 PortletResponse.createResourceURL 方法創建它。資源 URL 包含當前 Portlet 的瞬時狀態(Portlet 模式、窗口狀態和呈現參數 ),但不能為此狀態設置新值。資源 URL 可以有在資源 URL 上設置的其他資源參數。

通過調用 ResourceServingPortlet 接口的 serveResource() 方法, Portlet 不僅可以通過控制門戶訪問而對資源進行保護,並且 Portlet 容器不會呈現任何除 serveResource() 方法返回的內容之外的附加輸出。這樣,用戶由於可以直接通過操作響應對象而被賦予了更多的控制權限,並且沒有額外門戶請求的開銷 ,減輕了門戶服務的負載。而 Portal 服務器此時只是充當了一個代理服務器的作用。

JSR 286 資源服務的使用方法:

Portlet 類需實現 javax.portlet.Portlet 和 javax.portlet.ResourceServingPortlet 接口並實現 serveResource() 方法, 如 清單 4 所示:

清單 4. Portlet 對資源文件的訪問控制

public class TestPortlet implements Portlet,  ResourceServingPortlet 
{
  ......
  public void serveResource(ResourceRequest resourceRequest,
    ResourceResponse resourceResponse) throws PortletException,
    IOException {
    ...
    在此添加訪問控制等業務邏輯代碼
    ...
    PortletRequestDispatcher portletRequestDispatcher  = portletConfig
      .getPortletContext().getRequestDispatcher(
      "/WEB- INF/jsp/TestPortletResource.jsp");
    portletRequestDispatcher.include(resourceRequest, resourceResponse);
  }
  ......
}

使用 JSP 標簽通過 PortletResponse.createResourceURL 方法創建 RecourceURL:

清單 5. 創建資源訪問 URL

<a href="<portlet:resourceURL/>">Click me to request Resource  URL</a>

所保護的訪問資源,在此例中即為 TestPortletResource.jsp 。

接下來,我們就可以充分體驗 JSR 286 資源服務新特性所帶來的簡單便捷以及高性能了。

對照該介紹,讀者可參照本系列第 2 部分對資源服務特性的實例開發加深 對該部分相關內容的理解。

事件

JSR 286 定義的事件模型是一種松耦合的代理事件模型。在此模型中,Portlet 定義可以 接收以及在 Portlet 部署描述符中公布的事件。在運行時,門戶管理員(或業務用戶)可以將不同的 Portlet 連接在一起。

Portlet 事件服務並不是一個可信任消息服務(例如 JMS)的替代。很多情況下 Portlet 事件並不能總是保證能夠傳送到目的地 。因此 Portlet 必須能夠在部分或即使所有事件都不能正確接收的情況下仍然能夠工作。

另外,有的時候 Portlet 為了響應某一 個事件,也會向另外的 Portlet 發布新的事件,這樣就形成了事件的衍生代。這在一定程度上可能造成事件的死鎖,JSR 286 本身沒有對 衍生代做出限制,但是很多 Portlet 容器會定義事件的最大衍生代以防止死鎖的發生。讀者在開發相關應用時請注意其本身的限制。

事件聲明

對於一個事件的聲明包括三個部分,分別是事件的定義聲明、事件的發布載體聲明也就是發布該事件的 Portlet 聲明、事件接收載體的 Portlet 聲明。

事件定義聲明:我們需要在 portlet.xml 中使用 <event-definition> 元素對事件 進行聲明,並且該元素與 <portlet> 元素並列作為 <portlent-app> 的子元素。

清單 6. event-definition 聲明

<portlet-app id="myPortletApp" version="2.0">
 <portlet>
 ...
  </portlet>
 <event-definition> . . .</event-definition>
 ...
</portlet- app>

對於一個事件的聲明有兩點需要注意:事件的名稱和值的類型。對於事件名稱,JSR 286 既可以為事件定義默認的 命名空間,其作用域為所有未聲明 QName 的事件;也可以為事件單獨定義自己的 QName。對於 QName 和命名空間的理解,請讀者參考 XML 規范的相關文檔,本文不做詳細介紹。對於事件值的類型,既可以是簡單的 Java 對象,例如 Integer,String 等,也可以是預先定 義的 Java 復雜對象,但是前提是該對象必須實現 Serializable 接口。其中 <event-definition> 的具體格式如 清單 7 和 清單 8 所示:

清單 7. 默認命名空間下事件定義聲明

<default-namespace>http://cn.ibm.com/</default- namespace>
......
<event-definition>
  <name>event-with-simple-value</name>
   <value-type>java.lang.String</value-type>
</event-definition>

<event- definition>
  <name>event-with-complex-value</name>
  <value- type>com.ibm.jsr286.TestEventBean</value-type>
</event-definition>

清單 8. 自定義 QName 下事件定義聲明

<event-definition>
  <qname xmlns:key="http://www.ibm.com">event-with- simple-value</qname>
  <value-type>java.lang.Integer</value-type>
</event- definition>

<event-definition>
  <qname xmlns:key="http://www.ibm.com">event-with- qname</qname>
  <value-type>com.ibm.jsr286..TestEventBean</value-type>
</event- definition>

事件發布載體聲明:事件的發布載體聲明需要在 portlet.xml 的 <portlet> 元素中用 <supported-publishing-event> 關鍵字。對應事件聲明格式,事件發布載體 Portlet 聲明亦有默認命名空間和自定義命名空間以 及簡單對象和復雜對象的情況,見示例:

清單 9. 默認命名空間下事件發布聲明

<supported-publishing- event>
  <name>event-with-simple-value</name>
</supported-publishing-event>

<supported-publishing-event>
  <name>event-with-complex-value</name>
</supported- publishing-event>

清單 10. 自定義 QName 下事件發布聲明

<supported-publishing-event>
  <qname xmlns:key="http://www.ibm.com">event-with-simple-value</qname>
</supported-publishing- event>

<supported-publishing-event>
  <qname xmlns:key="http://www.ibm.com">event-with -complex-value</qname>
</supported-publishing-event>

事件接收載體聲明與事件發布載體聲明類似 ,事件的接收載體聲明需要在 portlet.xml 的 <portlet> 元素中用 <supported-processing-event> 關鍵字。見示例清單 11 和 清單 12:

清單 11. 默認命名空間下事件接收載體聲明

<supported-processing-event>
   <name>event-with-simple-value</name>
</supported-processing-event>

<supported- processing-event>
  <name>event-with-complex-value</name>
</supported-processing- event>

清單 12: 自定義 QName 下事件接收載體聲明

<supported-processing-event>
   <qname xmlns:key="http://www.ibm.com">event-with-simple-value</qname>
</supported-processing- event>

<supported-processing-event>
  <qname xmlns:key="http://www.ibm.com">event-with -complex-value</qname>
</supported-processing-event>

事件發布接收與處理

事件發布:我 們可以在希望發布事件的 Portlet 的 processAction() 方法裡,通過調用 ActionResponse 的 setEvent() 進行事件發布,setEvent() 方法的輸入參數為事件的名稱和對應的值,這些參數必須與我們前面在 portlet.xml 中的事件聲明一致。

清單 13. 事件發布

public class TestSenderPortlet implements Portlet 
{
  ......
  public void  processAction(ActionRequest request,
    ActionResponse response) throws PortletException,
     IOException {
    ......
    response.setEvent(eventName, eventObject);
    ......
   }
  ......
}

事件接收:事件的接收 Portlet 必須實現 javax.Portlet.EventPortlet 接口,事件的接收處 理則在該接口包含 processEvent() 方法中進行,JSR 286 定義該方法提供了兩個輸入參數: EventRequest 和 EventResponse,我們可以 通過調用 EventRequest 實例的 getEvent() 方法來獲得當前事件,該方法返回一個事件對象的實例,該實例封裝了事件的唯一標識和對 應的值。---www.bianceng.cn

清單 14: 事件接收

public class TestReceiverPortlet implements Portlet,EventPortlet 
{
  ......
  public void processEvent(EventRequest request,
    EventResponse response) throws  PortletException,
    IOException {
    ......
    Event event = request.getEvent();
    ......
  }
  ......
}

事件處理:獲得事件對象後,我們也可以通過 getQNames() 方法或 者 getName() 獲得事件的名稱。兩種獲得事件方法的區別是 getQNames() 可以得到事件的全稱標識,而 getName() 只是取得本地標識名 。而取得事件的值則可以通過事件的 getValue() 方法獲得。

清單 15: 事件處理

......
public void  processEvent(EventRequest request,
  EventResponse response) throws PortletException,
  IOException  {
  ......
  Event event = request.getEvent();
  String name = event.getName();// 或者  String qname = event.getQNames();
  String value = event.getValue();
  ......
}
......

GenericPortlet API 的變化

在 JSR 168 Portlet 的開發中,開發者通常繼承抽象類 javax.portlet.GenericPortlet 來實現自己的 Portlet 邏輯代碼。同 JSR 168 相比, JSR 286 的 GenericPortlet 增加了 javax.portlet.EventPortlet 和 javax.portlet.ResourceServingPortlet 接口的實現,從而增加了事件處理和資源服務的功能。讀者可 以從 類圖 1 和 類圖 2 看出 JSR 286 GenericPortlet API 的變化。

圖 1. JSR 168 GenericPortlet 類圖

圖 2. JSR 286 GenericPortlet 類圖

共享呈現參數

我們先來看一看共享呈現參數的官方介紹:共享呈現用於在 Portlet 之間共享呈現參數,從而創建一個頁面上下 文。共享呈現參數在 portlet.xml 文件中聲明。如果這些參數不是空值,Portlet 將自動接收它們。與非共享呈現參數相比,如果應該更 改值,Portlet 僅需要設置共享呈現參數。

共享呈現參數,顧名思義,就是指 Portlet 之間共享參數,每一個 Portlet 對該參數 的修改都能夠直接被另外支持該參數 Portlet 所獲得。共享呈現參數與 JSR 168 中已經有私有呈現參數的區別就在於,私有呈現參數只 為 Portlet 內部使用,而共享呈現參數則為多個 Portlet之間通信協作而設置。共享呈現參數與事件相比的優勢就在於避免了事件處理過 程調用的繁瑣。

我們舉一個簡單的事例來說明共享呈現參數的優點。假如我們開發了一個關於天氣的 Portlet, 這個 Portlet 可 以根據選擇的城市來顯示該城市的天氣情況。我們為這個 Portlet 定制了郵政編碼這個共有呈現參數來表示用戶選擇的城市。這樣,如果 我們再開發一個也有這個共享呈現參數的 Portlet,例如顯示該城市地圖或者旅游信息的 Portlet。在這種情況下,當我們修改天氣 Portlet 所選擇的城市的話,地圖以及旅游信息的 Portlet 也會自動做出相應變化。從而實現了不同 Portlet 之間的協作。

共享 呈現參數的聲明

對共享呈現參數的使用聲明包括兩個部分,對共享呈現參數定義的聲明和支持共享呈現參數的 Portlet 聲明。

共享呈現參數定義聲明:對於共享呈現參數定義的聲明必須在 portlet.xml 部署文件中使用 <public-render-parameter> 關鍵字,該元素與 <portlet> 元素並列為 <portlet-app> 的分支。

清單 16. 共享呈現參數定義聲明

<portlet-app ...>
  <portlet>
    <portlet-name>Portlet A</portlet- name>
  ...
  </portlet>
  ...
  <public-render-parameter>
     <identifier>public-render-param1</identifier>
  </public-render-parameter>
  <public- render-parameter>
    <identifier>public-render-param2</identifier>
  </public-render- parameter>
</portlet-app>

支持共享呈現參數 Portlet 聲明:對於支持共享呈現參數的 Portlet 的聲明 需要在 portlet.xml 中 <portlet> 元素中使用 <supported-public-render-parameter> 關鍵字。

清單 17. 共享呈現參 數 Portlet 定義聲明

<portlet>
  <portlet-name>Portlet B</portle-name>
   ......
  <supported-public-render-parameter>
    <identifier>public-render- param1</identifier>
  </supported-public-render-parameter>
</portlet>

<portlet>
  <portlet-name>Portlet C</portle-name>
  ......
  <supported- public-render-parameter>
    <identifier>public-render-param2</identifier>
   </supported-public-render-parameter>
</portlet>

共享呈現參數的使用

與非共享呈現參數的 使用方法相同,共享呈現參數可以通過 ActionResponse 的 setRenderParameter("標識","值") 方法設定,並通過 RenderRequest 的 getParameter("標識") 來獲得。見 清單 18 和 清單 19

清單 18. Portlet A 設定共享呈現參數

...
public  void processAction(ActionRequest actionRequest,
    ActionResponse actionResponse) throws  PortletException, IOException {
  String publicRenderParamValue1 = actionRequest.getParameter("public-render -param1");
  actionResponse.setRenderParameter("public-render-param1", publicRenderParamValue1);
}
...

清單 19. Portlet B 獲取共享呈現參數

...
public void render(RenderRequest  renderRequest,
    renderResponse renderResponse) throws PortletException, IOException {
  ...
  String publicRenderParamValue1 = renderRequest.getParameter("public-render-param1"); 
  ...
}
......

Portlet 過濾器

Portlet 過濾器是 JSR 286 提供的有一個非常重要的新特性。事實上,在 JSR 286 之前 ,就已經有很多廠商(包括 IBM)自定義擴展了 JSR 168,提供了過濾器功能。由此可見,Portlet 過濾器的重要性。為了避免各種廠商 不同 Portlet 過濾器的不兼容性,JCP(Java Community Process)對 JSR 286 定義了標准的過濾器實現。

什麼是 Portlet 過濾 器?

與 Servlet 相似,Portlet 過濾器可以使用戶可以改變一個 request 和修改一個 response。Filter 不是一個 Portlet,它 不能產生一個 response,它能夠在一個 request 到達 Portlet 之前預處理 request,也可以在離開 Portlet 時處理 response。換句話 說,過濾器其實是一個“Portlet chaining”(Portlet 鏈)。它能夠實現的功能包括:

在 Portlet 被調用之前截獲;

在 Portlet 被調用之前檢查 servlet request;

根據需要修改 request 頭和 request 數據;

根據需要修改 response 頭和 response 數據;

在 Portlet 被調用之後截獲;

Portlet 過濾器與 Servlet 過濾器

事實上,從宏 觀功能的角度看來,Portlet 過濾器和 Servlet 過濾器是很相似的。這是因為二者都可以聲明性地嵌入,從而截獲並修改請求和響應。但 是理解它們之間存在著很大的不同是非常重要的。在一定程度上,它們之間的差異是與 Servlet 和Portlet 之間的差異相聯系的: Servlet 過濾器是一個門戶級過濾器,它可以修改由一些小的部分(來自頁面上所有 Portlet 的響應)集合而成的整個門戶頁面;而 Portlet 過濾器只能用於那些小的部分。Servlet 過濾器(如果已經安裝的話)是接收和修改客戶端請求的第一個組件,同時也是修改對 客戶端的響應的最後一個組件(請參見圖 3)。

圖 3. 帶有 Servlet 過濾器和 Portlet 過濾器的客戶端請求事件序列

如圖 3 所示,Servlet 請求(步驟 1)在分派給一個或多個 Portlet 請求(步驟 3)之前首先通過一個 Servlet 過濾器鏈進行處理 (步驟 2)。在結果集聚到一起(步驟 6 和 7)之前,Portlet 請求進一步轉發到 Portlet 過濾器鏈進行處理(步驟 4)。接著,將集 聚的結果發送回 Servlet 過濾器進行處理,之後,將集聚的結果最終顯示給用戶(步驟 9)。

另外一點需要注意的是,Servlet 過濾器比 Portlet 過濾器的優先級別要高,容器將首先進行 Servlet 過濾,其次是 Portlet 過濾。一個過濾器鏈包含一個或多個過濾器 。在一個過濾器完成處理之後,新的請求和響應將傳送到鏈上的下一個過濾器;鏈上的最後一個過濾器調用目標資源(Servlet 或 Portlet)。

Portlet 過濾器的工作原理

Portlet 過濾器可以放置在 V2.0 規范提供的任何生命周期方法調用的前面或者後 面(processAction、processEvent、render、serveResource),而且還支持這些生命周期方法使用包裝的請求和響應。與 Servlet 過濾 器類似,Portlet 過濾器需要在 portlet.xml 部署描述符中進行定義,不同的是,servlet只有一個service()的請求處理方法,因此 servlet只有一種類型的過濾器。而portlet 卻有四種請求處理方法,於是有四種類型的過濾器,包括:

Action 過濾器

Render 過濾器

Resource 過濾器

Event 過濾器

下面我們來介紹四種過濾器的工作原理。

JSR 286 為 Portlet 過濾器提供了接口類 PortletFilter,該接口提供了兩個方法。

void init(FilterConfig config)
容器調用一次這 個方法來准備用於服務的過濾器。對象 filterConfig 使得過濾器能夠訪問配置參數以及對門戶上下文的引用。

void destroy()
這個方法是在將過濾器從服務移除之後調用的。這個方法使得過濾器能夠清除任何存放的資源。

JSR 286 為四種過濾器分別 定義了一個接口類,這四個接口類都繼承 PortletFilter 類,並分別添加了各自 doFilter() 方法。關於這幾個類之間的關系,請見下圖 :
圖 4. Portlet 過濾器繼承圖

四種過濾器分別對 Portlet 的四個方法進行攔截。用戶自定義的過濾器必須實現相應的過濾器接口,通過其 doFilter() 方法來實現 相應的動作。其對應關系見表 1:

表 1. 過濾器與攔截方法關系圖

過濾器 攔截方法 Action 過濾器 processAction(ActionRequest request, ActionResponse response) Render 過濾器 render(RenderRequest request, RenderResponse response) Resource 過濾器 serveResource(ResourceRequest request, ResourceResponse response) Event 過濾器 processEvent(EventRequest request, EventResponse response)

Portlet 過濾器的部署聲明

下面我們通過一個具體的 Portlet 過濾器部署實例來說明。參見清單 20:
清單 20. Portlet 過濾器聲明

<portlet-app ...>
  ...
  <filter>
    <filter- name>TestRenderFilter</filter-name>
    <filter-class>com.ibm.jsr286.TestRenderFilter</filter -class>
    <lifecycle>RENDER_PHASE</lifecycle>
  </filter>

   <filter>
    <filter-name>TestAllFilter</filter-name>
    <filter- class>com.ibm.jsr286.TestAllFilter</filter-class>
     <lifecycle>ACTION_PHASE</lifecycle>
    <lifecycle>RENDER_PHASE</lifecycle>
     <lifecycle>EVENT_PHASE</lifecycle>
    <lifecycle>RESOURCE_PHASE</lifecycle>
   </filter>

  <filter-mapping>
    <filter-name>TestRenderFilter</filter- name>
    <portlet-name>DocumentPortlet</portlet-name>
    </filter-mapping>

  <filter-mapping>
    <filter-name>TestAllFilter</filter-name>
     <portlet-name>Test*</portlet-name>
  </filter-mapping>
</portlet-app>

關 於 Portlet 過濾器有幾點需要聲明的是:

對於一個 Portlet 過濾器的聲明亦包括兩部分,過濾器的定義聲明以及過濾器的映射 聲明。

一個 Portlet 過濾器可以為多個 Portlet 服務,而且 一個 Portlet 可以同時有多個 Portlet 過濾器。

一個 Portlet 過濾器可以有多個生命周期階段,當然前提是該 Portlet 過濾器實現了相應過濾器接口。

Portlet 窗口

Portlet 窗口在 JSR 168 中僅間接地得到反映,並作為容器為 Portlet 范圍的會話條目生成的前綴的一部分。JSR 286 規范現在使該 Portlet 窗 口 ID 可通過請求供 Portlet 使用,簡單的說就是,PortletRequest 新增了一個方法 getWindowID(),可以獲得 Portlet 的窗口 ID,這 個 ID 是由容器生成的。在 Portal 容器中布局同一個 Portlet 多次的情況下,windowID 可以用來區分同一個 Portlet 的不同窗口,從 而可以使這些 Portlet 窗口緩存並呈現不同的數據。

Portlet 窗口支持的一個常見用例是在 Portlet 中緩存數據;例如,一個 Portlet,呈現所使用的數據是通過 web services 從遠端服務器獲得,而且網絡調用速度比較慢,且呈現的數據為只讀,這種情況下就可 以把 web services 獲得的數據和窗口 ID 關聯並緩存起來,在頻繁調用 Portlet 的時候,就不必頻繁等待 web services 的返回。

小結

本文在回顧 JSR 168 Portlet 的基礎上,對 JSR 286 Portlet 的新特性進行了詳細介紹。我們將在本系列的後兩部 分文章中對具體的應用程序開發流程進行詳細的闡述,敬請期待。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved