Java Portlet Tools:將 Java Web 應(yīng)用轉(zhuǎn)換為適應(yīng)性 Portlet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
作者:Andrew L… 文章來源:BEA dev2dev 點(diǎn)擊數(shù):69 更新時(shí)間:2006-7-29 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
【字體:小 大】 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
如果您有任何疑問,請(qǐng)到開發(fā)論壇上提問。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
摘要本文介紹如何將在門戶外運(yùn)行的 Web 應(yīng)用轉(zhuǎn)換為在 AquaLogic User Interaction 內(nèi)使用的適應(yīng)性 portlet。本文概述使用 Java Server Faces 或 Struts 等 Web 應(yīng)用框架時(shí)遇到的問題和一種解決這些問題的新工具 — Java Portlet Toolkit。本文還將探討 Java Portlet Toolkit 附帶的一些其它工具,如 PortletBean 和特定于門戶的 JSP 標(biāo)簽。 簡介:Java Web 應(yīng)用與 Java Portlet 應(yīng)用自從 Java servlet 和 Java Server Pages (JSF) 規(guī)范問世后,人們就為更簡易地編寫、配置和自定義 Java Web 應(yīng)用進(jìn)行了多次嘗試。大多數(shù)應(yīng)用都采用了“Model 2”架構(gòu),在這種架構(gòu)中,請(qǐng)求通過控制 servlet 路由到各個(gè) JSP 頁面,并顯示和修改 servlet 請(qǐng)求和會(huì)話附帶的 JavaBean 中的數(shù)據(jù)。此架構(gòu)采用 Smalltalk “模型-視圖-控制器”設(shè)計(jì)模型,極大程度地簡化了 Java Web 應(yīng)用的開發(fā)。一些Web 應(yīng)用框架,如Struts 和 Java Server Faces,允許開發(fā)人員配置請(qǐng)求路由,JavaBean 管理,驗(yàn)證及其它常用 Web 應(yīng)用任務(wù),而不必將這些功能硬編碼到 JSP 或 Java 類中,從而進(jìn)一步簡化了 Web 應(yīng)用開發(fā)。 Struts 和 JSF 等框架非常適合單機(jī) Web 應(yīng)用,因?yàn)檫@些框架能執(zhí)行大部分請(qǐng)求處理、驗(yàn)證和導(dǎo)航的工作,使開發(fā)人員有時(shí)間定義應(yīng)用所需的業(yè)務(wù)邏輯。遺憾的是,由于這些框架依賴于表單 post 和重定向來管理應(yīng)用導(dǎo)航,其結(jié)構(gòu)通常不適合在門戶應(yīng)用中使用。此外,由于框架沒有唯一標(biāo)識(shí)單個(gè) Web 應(yīng)用范圍以外的頁面元素的功能,大多數(shù)框架都很難轉(zhuǎn)換到多 portlet 環(huán)境(在這種環(huán)境中,一個(gè) Web 應(yīng)用可能會(huì)有多個(gè)實(shí)例作為 portlet 顯示在頁面上)。 理想情況下,應(yīng)該有一種方式可以轉(zhuǎn)換 Struts、JSF 或任何 JSP/servlet 應(yīng)用,使它們既可以在 portlet 中使用也可以作為單機(jī) Web 應(yīng)用使用,而不必對(duì)應(yīng)用代碼或配置文件進(jìn)行更改。所幸的是,Plumtree Java Portlet Tools 庫的開發(fā)版正好可以使開發(fā)人員達(dá)成此目的。此外,該庫還為 EDK 功能提供 JavaBean 包裝器。EDK 是一組工具庫,允許開發(fā)人員訪問請(qǐng)求頭中編碼的 portlet 信息和執(zhí)行遠(yuǎn)程服務(wù)任務(wù),例如,從 Collaboration 和 Search 等門戶應(yīng)用訪問數(shù)據(jù)。Java Portlet Toolkit EDK 包裝器 bean 允許開發(fā)人員使用 JSP 2.0 Expression Language 來獲取和設(shè)置 portlet 屬性、設(shè)置和首選項(xiàng)。最后,它還包括一套自定義標(biāo)簽,為訪問隨處刷新和 PCC 事件處理等適應(yīng)性 portlet 技術(shù)提供簡化訪問,使開發(fā)人員在不必編寫任何 JavaScript 的情況下就能執(zhí)行復(fù)雜的 DHTML 操作。 本文的讀者應(yīng)熟悉 Java、Java servlets、JSP 和 JSP 標(biāo)簽庫技術(shù)。希望將簡單 Java 應(yīng)用轉(zhuǎn)換為適應(yīng)性 portlet 的開發(fā)人員可只閱讀 Servlet Filter PTPortletFilter這一節(jié),跳過討論打包在Java Portlet Tools 庫中的附加特性的其他章節(jié)。希望充分利用適應(yīng)性 portlet 技術(shù)的開發(fā)人員則應(yīng)閱讀整篇文章。 Servlet Filter 和 PTPortletFilterJava Servlet 2.3 規(guī)范包含一個(gè)名為 Filter 的新類。Filter 是在 Java servlet 應(yīng)用的 web.xml 文件中配置的,在 servlet 請(qǐng)求和響應(yīng)發(fā)送到 JSP 和 servlet 類之前或之后都可以截取和修改它們。Java Portlet Tool 提供一種特殊的 Servlet Filter,稱為 PTPortletFilter,該類截取從 Web 應(yīng)用發(fā)送的 HTML 并重寫,使它可包括在 Plumtree portlet 中。此重寫過程會(huì)執(zhí)行以下幾種操作:
PTPortletFilter 通過將以下 XML 添加到 Web 應(yīng)用的 web.xml 配置文件來聲明: <filter> <filter-name>Adaptive Portlet Filter</filter-name> <filter-class>com.plumtree.remote.filter.PTPortletFilter</filter-class> <init-param> <param-name>filter.config.file</param-name> <param-value>C:\portlettools\apps\carstore\conf\custom-filter.xml</param-value> </init-param> <init-param> <param-name>filter.log.file</param-name> <param-value>C:\portlettools\apps\carstore\logs\jpt.log</param-value> </init-param> <init-param> <param-name>filter.log.level</param-name> <param-value>debug</param-value> </init-param> <init-param> <param-name>jsxml.version</param-name> <param-value>177643</param-value> </init-param> <init-param> <param-name>portal.imageserver.alternate</param-name> <param-value>https://plumtree/imageserver</param-value> </init-param> </filter> <filter-mapping> <filter-name>Adaptive Portlet Filter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> 所有篩選器初始化參數(shù)都是可選的,如果您不想執(zhí)行任何篩選器日志記錄或自定義操作,則只需添加 filter 類和 URL 映射即可。對(duì)于較復(fù)雜的門戶配置,您可能需要添加備用的imageserver 或日志記錄初始化參數(shù)。PTPortletFilter 識(shí)別的初始化參數(shù)如下:
有關(guān) PTPortletFilter 如何重寫響應(yīng) HTML 的示例,請(qǐng)看表單中的一個(gè)簡單提交按鈕: <form id="myform" action="next.jsp"> <input type="submit" name="action" value="Submit" onchange="alert(‘Saving info...‘)"> ... </form> 如果不作修改,此按鈕將導(dǎo)致整個(gè)門戶頁提交,并只對(duì)單擊了按鈕的 portlet 返回內(nèi)容,從而使該 portlet 接收門戶頁的全部內(nèi)容。但是,PTPortletFilter 會(huì)重寫標(biāo)簽,以使用隨處刷新: <form id="myform_203" action="http://host/portal/server.pt/gateway/PTARGS_0_16_203_0_0_43/http%3B/app/next.jsp"> <input type="button" name="action" value="Submit" onchange="alert(‘Saving info...‘); postback_203(document.getElementById(‘myform_203‘), document.getElementById(‘pt-portlet-java-203‘), {‘a(chǎn)ction‘:‘Submit‘});"> ... </form> 指向 Web 應(yīng)用資源(且目的是刷新當(dāng)前頁)的超級(jí)鏈接將被重寫,從而使它們能夠執(zhí)行隨處刷新請(qǐng)求。例如,在以下鏈接中: <a href="next.jsp">Link in this window</a> <a href="next.jsp" target="new">Link in another window</a> <a >Link to another site</a> 只有第一個(gè)鏈接會(huì)導(dǎo)致門戶出現(xiàn)問題。像上面的表單示例一樣,單擊此鏈接會(huì)使該 portlet 接收整個(gè)門戶頁的內(nèi)容。只有此鏈接會(huì)被重寫,以執(zhí)行隨處刷新請(qǐng)求。 <a onclick="linkback_203(‘http://host/portal/server.pt/gateway/PTARGS_0_16_203_0_0_43/http%3B/app/next.jsp‘, document.getElementById(‘pt-portlet-java-203‘); return false;" href="#">Link in this window</a> <a href="http://host/portal/server.pt/gateway/PTARGS_0_16_203_0_0_43/http%3B/app/next.jsp" target="new">Link in another window</a> <a >Link to another site</a> 最后,Web 應(yīng)用中按計(jì)劃提交表單的所有 JavaScript 都會(huì)被重寫,以執(zhí)行隨處刷新。所有引用表單的 JavaScript 都會(huì)被重寫,以根據(jù)含有追加的 portlet ID 的唯一 ID 引用表單。 當(dāng) Web 應(yīng)用被視為單機(jī) Web 應(yīng)用而非 portlet 中的遠(yuǎn)程 Web 服務(wù)時(shí),PTPortletFilter 會(huì)被禁用。如果通過門戶的網(wǎng)關(guān)運(yùn)行 Web 應(yīng)用中的某個(gè)頁面并在 portlet 中顯示,則 PTPortletFilter 將按原樣顯示該 Web 應(yīng)用的 HTML 內(nèi)容。 PortletBeanJava Portlet Tools 提供一種專門的 JavaBean, 供 JSP scriptlets 和 JSP 表達(dá)式語言使用。有關(guān) JSP 表達(dá)式語言如何工作的詳細(xì)信息,請(qǐng)參閱 Sun 的 JSP 文檔。PortletBean 是 EDK 和客戶端 portlet API 功能的 JavaBean 包裝器。它為以下各項(xiàng)提供屬性的 getter 和 setter 方法:
此 bean 使用屬性名“portlet”自動(dòng)連接到通過 PTPortletFilter 的每個(gè) ServletRequest。開發(fā)人員可通過 PortletBean 引用 EDK 方法值,而不必在 JSP 的 scriptlet 中構(gòu)建 IPortletContext 和 IPortletRequest 對(duì)象。這看似只是 JavaBean 語法中已有的包裝功能,但在 Java Web 應(yīng)用中,PortletBean 可以用來實(shí)現(xiàn)強(qiáng)大的功能。例如,假設(shè) JSF Web 應(yīng)用開發(fā)人員想要?jiǎng)?chuàng)建一個(gè)個(gè)人資料 portlet,該 portlet 可以設(shè)置用戶首選項(xiàng)并觸發(fā) PCC 事件,通知其它已設(shè)置首選項(xiàng)的portlet。JSP 頁中的標(biāo)記將為如下所示: <f:view> <h:form> <b>Personal Profile Information:</b><br> <h:panelGrid columns="2"> <h:outputText value="Name:"/> <h:inputText value="#{portlet.userSettings.name}"/> <h:outputText value="Age:"/> <h:inputText value="#{portlet.userSettings.age}"/> <h:outputText value="Height:"/> <h:inputText value="#{portlet.userSettings.height}"/> <h:outputText value="Weight:"/> <h:inputText value="#{portlet.userSettings.weight}"/> <h:outputText value="Nationality:"/> <h:inputText value="#{portlet.userSettings.nationality}"/> </h:panelGrid> <h:commandButton action="success" value="Submit" onclick="#{portlet.raiseEventJS[‘submitinfo‘]}"/> </h:form> </f:view> 這一簡單的 JSP 將使用戶首選項(xiàng)值顯示為 <input type="text"> 標(biāo)簽的值并在提交表單后即設(shè)置成功。這被稱為值綁定(value binding),它使 JSF 應(yīng)用自動(dòng)從 servlet 請(qǐng)求中設(shè)置 bean 屬性值,而無需開發(fā)人員編寫任何請(qǐng)求處理代碼。如果沒有 PortletBean,則 JSF 應(yīng)用必須創(chuàng)建 IPortletContext、IPortletRequest 和 IPortletResponse 對(duì)象,檢索每個(gè)設(shè)置的設(shè)置值并使用 JSP scriptlet 將其插入到輸入標(biāo)簽中,最后在服務(wù)器端的 handler 類中處理請(qǐng)求,而該類必須從請(qǐng)求獲取每個(gè)設(shè)置值并將其手動(dòng)設(shè)置到 IPortletResponse。此請(qǐng)求處理代碼毫無疑問將是硬騙碼,如果需要更多首選項(xiàng)設(shè)置時(shí),將很難修改。 另請(qǐng)注意 <h:commandButton> 標(biāo)簽。此標(biāo)簽有一個(gè) onclick 屬性值,該值觸發(fā)可被門戶頁面中其它 portlet 中的注冊(cè) PCC 事件處理程序捕捉的 JavaScript PCC 事件。在本例中,PortletBean 屬性解析為: onclick="document.PCC.RaiseEvent (‘urn:/plumtree.com/adaptiveportlets‘, ‘submitinfo‘);" 有關(guān)使用 PortletBean EDK 屬性或使用 PortletBean 來生成客戶端 JavaScript 的詳細(xì)信息,請(qǐng)參見:附錄 B:PortletBean API。 Java Portlet Tools 標(biāo)簽JSP 規(guī)范允許開發(fā)人員定制自定義標(biāo)簽庫,當(dāng) JSP 評(píng)估時(shí),這些標(biāo)簽庫可以生成自定義 UI 組件顯示在 Web 應(yīng)用中。Java Portlet Tools 庫提供一組自定義標(biāo)簽,使開發(fā)人員能利用客戶端適應(yīng)性 portlet 技術(shù)。通過在 JSP 頁添加 taglib 指令,即可將自定義標(biāo)簽庫添加到 JSP 頁面中,例如: <html> <head> <title>Car Store</title> </head> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://plumtree.com/javaportlettools" prefix="portlet" %> <body> ... </body> </html> http://plumtree.com/javaportlettools URI 用于唯一地標(biāo)識(shí) Plumtree Java Portlet Tools 標(biāo)簽庫。在此庫中,您可找到以下標(biāo)簽。(注意:單擊下面左邊欄中的鏈接后,可能需要刷新瀏覽器才能訪問登錄頁面。)
有些標(biāo)簽與 PortletBean 提供的功能重復(fù)。例如,在一個(gè) JSF 應(yīng)用中,開發(fā)人員可以通過三種不同的方式觸發(fā) PCC 事件: <h:outputLink onclick="#{portlet.raiseEventJS[‘myevent‘]}"> <h:outputLink onclick="<%= ((PortletBean) request. getAttribute("name")).raiseEventJS("myevent") %>"> <a onclick="<portlet:raiseEvent eventname="myevent"/>"> 功能重復(fù)的原因是,JSP 表達(dá)式語言只能在 JSP 2.0 標(biāo)簽的自定義標(biāo)簽屬性中起作用,而 scriptlets 讀寫太麻煩。許多 Web 應(yīng)用框架特別阻止用戶在其 JSP 中依賴 scriptlet。Java Portlet Tools 提供的自定義標(biāo)簽允許開發(fā)人員在沒有或不能使用表達(dá)式語言的情況下避免使用 scriptlet。其它標(biāo)簽,如 <portlet:onEvent> 標(biāo)簽,不適合作為 PortletBean 屬性使用,因?yàn)樗鼈儠?huì)生成大量復(fù)雜的 JavaScript 和 HTML,或者因?yàn)樗鼈儾皇怯脕碓谄渌鼧?biāo)簽中作為屬性值使用的。開發(fā)人員應(yīng)參考“附錄 C:常見問題”以了解何時(shí)使用自定義標(biāo)簽和 PortletBean。 總結(jié)Java Portlet Toolkit 使 Web 應(yīng)用能夠輕松轉(zhuǎn)換為 portlet。只要在 Web 應(yīng)用的 web.xml 配置文件加上篩選器,Java Portlet Toolkit 就會(huì)重寫 Web 應(yīng)用 HTML,使之能在門戶環(huán)境中有效運(yùn)行。此篩選器可根據(jù)特定 Web 應(yīng)用的需求方便地進(jìn)行配置。此外,Java Portlet Toolkit 還提供一組 JavaBean 和 JSP 標(biāo)簽,使 Java Web 應(yīng)用的開發(fā)和對(duì)門戶資源的訪問更為簡單。 參考
附錄 A: PTPortletFilter 配置 XMLPTPortletFilter 事實(shí)上是一種更通用的 ResponseFilter 類的子類,該類也執(zhí)行 HTTP 響應(yīng)文本(不一定是 HTML)篩選,并且不依賴 HttpServletRequest 的網(wǎng)關(guān)。PTPortletFilter 逐行修改 HTML,意味著它一次只執(zhí)行一行,而不是整個(gè) HTML 響應(yīng)。但當(dāng) HTML 標(biāo)簽跨越多行時(shí)例外,例如: <a href="myapp/chooseLocale.faces" onclick="alert(‘Choose Locale‘);"> Choose Locale</a> 在本例中,PTPortletFilter 會(huì)將標(biāo)簽所跨越的所有行當(dāng)作單個(gè) HTML 行進(jìn)行篩選。 PTPortletFilter 在啟動(dòng)時(shí)會(huì)加載一個(gè) XML 配置文件,該文件定義 PTPortletFilter 對(duì)被篩選的 Web 應(yīng)用的響應(yīng) HTML所執(zhí)行的篩選操作。除以上配置文件中定義的篩選操作外,PTPortletFilter 還執(zhí)行幾項(xiàng)其它功能:
篩選器的配置 XML 定義了兩組可對(duì)響應(yīng) HTML執(zhí)行操作的對(duì)象:FilterAppender 和 FilterOperation。 FilterAppenderFilterAppender 是將 HTML 附加到響應(yīng) HTML開頭和末尾部分的 Java 類。由于此操作只對(duì)每次請(qǐng)求執(zhí)行一次,因此與使用FilterOperation 在響應(yīng)的開頭和末尾插入 HTML相比,定義一個(gè)類來執(zhí)行此步驟更有效率,這是由于FilterOperation 會(huì)對(duì)響應(yīng) HTML 的每一行執(zhí)行操作。Appender 是通過引用生成 appender 的類在配置 XML 文件中進(jìn)行聲明的。 <httpfilter> <appenders> <appender class="com.plumtree.remote.filter.appender.AdaptivePortletAppender"/> </appenders> <operations> ... </operations> </httpfilter> 在實(shí)例化時(shí),Appender 都調(diào)用同一 init() 函數(shù),該函數(shù)取 PTPortletFilter 的 FilterConfig 作為參數(shù)。這樣,appender 就可以訪問在定義篩選器的 web.xml 中設(shè)置的所有初始化參數(shù)。 PTPortletFilter 在沒有 appender 類的情況下也可運(yùn)行,但我們定義了一個(gè)有用的 appender,它允許 Java Web 應(yīng)用框架在門戶環(huán)境內(nèi)部能運(yùn)行:AdaptivePortletAppender。此appender附加了JSXML JavaScript組件,它允許從Web應(yīng)用程序中發(fā)出隨處刷新請(qǐng)求。AdaptivePortletAppender 使用 JSRegistry 與 imageserver 聯(lián)系,并生成應(yīng)包含在頁面中的JavaScript文件清單,以實(shí)例化客戶端 JavaScript 中的 JSXML 對(duì)象。此外,AdaptivePortletAppender 還添加了幾個(gè)簡化的功能,使隨處刷新請(qǐng)求更容易生成。最后,appender 將 Web 應(yīng)用生成的內(nèi)容包裝在具有唯一 ID pt-portlet-java-[portletID] 的 <div> 標(biāo)簽中。每次用戶啟動(dòng)隨處刷新請(qǐng)求時(shí),該唯一 ID 就用作目標(biāo) HTML 要素;而此 <div> 標(biāo)簽中的內(nèi)容將被響應(yīng)取代。 FilterOperationPTPortletFilter 配置 XML 定義的第二種對(duì)象是 FilterOperation 子類。每個(gè) FilterOperation 子類代表一個(gè)將對(duì)文本的每一行執(zhí)行的特定文本處理操作。FilterOperation 都構(gòu)建在操作樹中,使特定操作只有在其父操作成功時(shí)才會(huì)發(fā)生。以下是操作 XML 的例子: <operations> <grabtag> <tag>title</tag> <token>TITLE</token> </grabtag> <match> <pattern></ body[^>]*></pattern> <flags>i</flags> <operations> <grabattribute> <tag>body</tag> <attribute>onload</attribute> <token>BODYONLOAD</token> </grabattribute> <grabattribute> <tag>body</tag> <attribute>bgcolor</attribute> <token>BODYBGCOLOR</token> </grabattribute> <if> <token>BODYBGCOLOR</token> <exists/> <operations> <insert> <before><body[^>]*></before> <markup><div color=@BODYBGCOLOR@></markup> </insert> </operations> </if> <replace> <pattern><(/ )body</pattern> <with><?div</with> <flags>i</flags> </replace> </operations> </match> ... </operations> 提供了幾種類型的 FilterOperation。篩選器操作通過調(diào)用 excecute 方法執(zhí)行,該方法使用兩個(gè)自變量:來自 HTTP 響應(yīng) HTML 的文本的下一行文本,以及包含名稱/值對(duì)的映射,這些名稱/值對(duì)可用來替換找到的令牌。在執(zhí)行該操作的過程中,可能會(huì)向令牌“映射”里添加新的值或刪除一些值,文本行也可能在傳遞到樹中的下一操作之前被更改。令牌是通過以“@”字符包圍令牌值名稱來定界的,如 @TOKEN@。令牌可用于各種篩選器操作值,也可以用作存儲(chǔ)處理響應(yīng) HTML 時(shí)收集的數(shù)據(jù)的變量;例如,可創(chuàng)建一個(gè)令牌來存儲(chǔ)有關(guān)響應(yīng) HTML 是否使用了 <title> 標(biāo)簽。還可以對(duì)這些令牌變量執(zhí)行條件測(cè)試,以確定對(duì)文本行執(zhí)行操作的篩選器操作流。 操作分為三類:文本操作、條件測(cè)試和令牌設(shè)置。 文本操作以下操作可對(duì)傳遞到操作的文本執(zhí)行,并且可將該文本的變更版本傳遞到下一操作中。(注意:單擊下表左邊欄中的鏈接后,可能需要刷新才能訪問登錄頁面。)
條件操作以下操作在確定是否對(duì)文本行執(zhí)行了子操作中起著監(jiān)視作用。條件操作對(duì)響應(yīng)文本行和令牌值執(zhí)行條件測(cè)試。如果通過條件測(cè)試,則執(zhí)行條件操作的子操作。
令牌設(shè)置操作以下操作可以響應(yīng)文本行中提取值,并將這些值設(shè)置為令牌映射中的變量。
其它操作
創(chuàng)建自定義篩選器操作 如果開發(fā)人員想對(duì)以上操作列表中未提到的響應(yīng) HTML 執(zhí)行某種操作,PTPortletFilter 支持使用自定義 FilterOperation 對(duì)象。要?jiǎng)?chuàng)建自定義操作,開發(fā)人員必須創(chuàng)建 FilterOperation 類的子類并實(shí)現(xiàn) execute() 方法。此外,開發(fā)人員可能要覆蓋該類的 init() 方法,以對(duì)操作執(zhí)行任何初始化。 要在 PTPortletFilter 配置 XML 文件中聲明自定義操作,開發(fā)人員必須將以下 XML 添加到文件中: <httpfilter> <operations> ... <operation class="com.plumtree.remote.fitler.operations.MyCustomOperation"> <property name="property1">some value</property> <property name="property2">some other value</property> <operations> <set> <token>foo</token> <value>bar</value> </set> </operations> </operation> ... </operations> </httpfilter> 請(qǐng)注意,F(xiàn)ilterOperation 的所有子類都支持內(nèi)建的子操作,以上示例添加了自定義操作 MyCustomOperation 的 <set> 操作。但是,因?yàn)樽硬僮鞯膱?zhí)行通常依賴于父操作的成功執(zhí)行,如果創(chuàng)建自定義 FilterOperation 的開發(fā)人員想要對(duì)響應(yīng)文本執(zhí)行子操作,他們必須在 execute() 方法中調(diào)用 executeSubOperations() 方法。 標(biāo)準(zhǔn)令牌值 傳遞到 FilterOperation.execute() 方法中的令牌“映射”中包含幾個(gè)由 PTPortletFilter 自動(dòng)設(shè)置的令牌值。此外,還可以對(duì) PTPortletFilter 進(jìn)行設(shè)置,使特定設(shè)置類型(Admin、Community、Portlet 和 User 等)的所有值都可包括到令牌“映射”中。這樣,篩選器操作可以引用作為被 PTPortletFilter 轉(zhuǎn)換的 portlet 的部分首選項(xiàng)的令牌值。 標(biāo)準(zhǔn)令牌值包括:
此外,開發(fā)人員還可以在 PTPortletFilter 的 web.xml 聲明中設(shè)置初始化參數(shù),如果參數(shù)設(shè)置為 true,則將特定設(shè)置類型的所有首選項(xiàng)包括到令牌“映射”中。這樣可以使 portlet 設(shè)置控制 Web 應(yīng)用的篩選方式。例如,可以設(shè)計(jì)一組篩選器操作,這些操作只有在令牌“映射”中找到特定首選項(xiàng)時(shí)才執(zhí)行。這些初始化參數(shù)包括:
附錄 B:PortletBean APIPortletBean 為編寫專在 portlet 上運(yùn)行的 Java Web 應(yīng)用提供一套有用的工具。PortletBean 的 API 模擬 EDK IPortletRequest 接口和即將推出的 Plumtree 門戶中發(fā)布的客戶端 “PTPortlet” 對(duì)象 JavaScript。PortletBean 以屬性形式自動(dòng)附加到每個(gè) HttpServletRequest。要從 JSP 或 servlet 訪問 PortletBean ,開發(fā)人員可以使用以下靜態(tài)方法: PortletBean bean = PTPortletFilter.getPortlet(request); 雖然這種訪問 PortletBean 的方法適用于 JSP scriptlet,但不適用于從 JSP 表達(dá)式語言中訪問 PortletBean。在標(biāo)準(zhǔn) JSP 表達(dá)式語言中,可使用以下語法引用 PortletBean: <jsp:useBean id="portlet" scope="request" class="com.plumtree.remote.filter.bean.PortletBean"/> ... <html:link href="#" onclick="${portlet.raiseEventJS[‘testevent‘]}">Click here</html:link> 或者 <html:link href="#" onclick="${requestScope.portlet.raiseEventJS[‘testevent‘]}">Click here</html:link> 最后,Java Server Faces與擴(kuò)展的表達(dá)式語言包裝在一起,可自動(dòng)解析請(qǐng)求、會(huì)話或應(yīng)用程序上下文中的JavaBean。 <h:outputLink value="#" onclick="#{portlet.raiseEventJS[‘testevent‘]}> <f:verbatim>Click here</f:verbatim><</h:outputLink> 用于 EDK 功能的 PortletBean API以下方法用作符合JavaBean的EDK功能包裝器,該功能由 IPortletContext、IPortletRequest 和 IPortletResponse。如前所述,使用 EDK 功能的 JavaBean 包裝器的主要優(yōu)勢(shì)是允許在 JSP 表達(dá)式語言中使用 PortletBean。(注意:單擊下面表格左邊欄的鏈接后,可能需要刷新瀏覽器才能訪問登錄頁面。) 以下函數(shù)是獲取 portlet 屬性值的標(biāo)準(zhǔn) getter/setter 函數(shù):
除標(biāo)準(zhǔn) getter 和 setter 外,PortletBean 還允許開發(fā)人員為 portlet 獲取各種用來存儲(chǔ) portlet 首選項(xiàng)值的設(shè)置集合(Admin、Community、Portlet、CommunityPortlet、User 和 UserInfo)。在 EDK 中,這些設(shè)置值以打破標(biāo)準(zhǔn) getter/setter 設(shè)計(jì)模式的方式進(jìn)行檢索和設(shè)置。具體來說,就是必須從 IPortletRequest 對(duì)象檢索 portlet 設(shè)置并在 IPortletResponse 對(duì)象上進(jìn)行設(shè)置。遺憾的是這種方式使得我們很難在 JSP 表達(dá)式語言中無縫地獲取和設(shè)置 portlet 設(shè)置。要解決此問題,需創(chuàng)建一個(gè) SettingsBean 對(duì)象,以提供 java.util.Map 接口來獲取設(shè)置值并將這些值設(shè)置到特定設(shè)置集合中。SettingsBean 會(huì)擴(kuò)展“映射”并覆蓋標(biāo)準(zhǔn)的 put(Object key, Object value) 方法,使輸入到“映射”中的項(xiàng)實(shí)際上設(shè)置在 IPortletResponse 上。以下方法允許用戶訪問每個(gè) portlet 設(shè)置類型的 SettingsBean 對(duì)象:
SettingsBean 在 Java Server Faces 應(yīng)用中尤其有用。將設(shè)置投射為“映射”可使 JSF 組件值綁定獲取和設(shè)置不同的設(shè)置。簡單地說,值綁定是具有 JavaBean 屬性值(或本例中的“映射”條目)的 UI 組件的值之間的顯式連接。例如,以下 JSF 代碼: <h:inputText value=" #{portlet.adminSettings[‘my.pref.value‘]}"> 確保顯示時(shí),標(biāo)簽生成的文本輸入字段會(huì)顯示自動(dòng)填充到文本字段的 Admin 設(shè)置值“my.pref.value”。當(dāng)文本字段所在的表單發(fā)送到服務(wù)器后,值綁定會(huì)自動(dòng)從請(qǐng)求獲取提交的文本字段值并將其設(shè)置為“my.pref.value” Admin 設(shè)置的值。 用于客戶端功能的 PortletBean APIPortletBean 還提供了生成客戶端JavaScript的方法,這些JavaScript可包含在 HTML 標(biāo)簽處理程序或內(nèi)嵌于JSP 的腳本中。PortletBean 生成的腳本使得訪問適應(yīng)性 portlet 功能更為簡單,從而方便地創(chuàng)建動(dòng)態(tài)的多 portlet 應(yīng)用。就當(dāng)前版本而言,PortletBean API 支持三種類型的適應(yīng)性 portlet 操作:觸發(fā) PCC 事件,獲取會(huì)話首選項(xiàng)和設(shè)置會(huì)話首選項(xiàng)。PCC 事件是JavaScript事件,它由 portlet 觸發(fā)并由在客戶端 PCC 對(duì)象上注冊(cè)的事件處理程序偵聽。這些事件偵聽程序可位于觸發(fā)事件的 portlet 或者其它 portlet 中。 為 PortletBean 生成 API 的 JavaScript 具有以 JSP 表達(dá)式語句和 JSP scriptlet 生成 JavaScript 的方法。因此,開發(fā)人員可使以下類型的調(diào)用以 JSP scriptlet 生成 JavaScript: <%= portlet.raiseEventJS("eventname") %> <%= portlet.raiseEventJS("mynamespace", "eventname") %> <%= portlet.raiseEventJS("mynamespace", "eventname", javaMap) %> <%= portlet.getSessionPrefJS("prefname") %> <%= portlet.getSessionPrefJS("namespace","prefname") %> <%= portlet.setSessionPrefJS("prefname","value") %> <%= portlet.setSessionPrefJS("namespace","prefname","value") %> 并使其生成以下 JavaScript: document.PCC.RaiseEvent(‘urn://plumtree.com/adaptiveportlets‘, ‘eventname‘) document.PCC.RaiseEvent(‘mynamespace‘, ‘eventname‘) document.PCC.RaiseEvent(‘mynamespace‘, ‘eventname‘, {key:‘value‘, key2:‘value2‘}) document.PCC.GetSessionState(‘urn://plumtree.com/adaptiveportlets‘, ‘prefname‘) document.PCC.GetSessionState(‘mynamespace‘, ‘prefname‘) document.PCC.SetSessionState(‘urn://plumtree.com/adaptiveportlets‘, ‘prefname‘, ‘value‘) document.PCC.SetSessionState(‘mynamespace‘, ‘prefname‘, ‘value‘) PortletBean 也具有生成屬性的 JavaScript,可執(zhí)行與以上 scriptlet 相同的功能,但使用的是 JSP 表達(dá)式語言。以下表達(dá)式語句也可生成上述 JavaScript: ${portlet.raiseEventJS[‘eventname‘]} ${portlet.raiseEventJS[‘mynamespace, eventname‘]} ${portlet.raiseEventJS[‘mynamespace, eventname, {key:value, key2:value2}‘]} ${portlet.getSessionPrefJS[‘prefname‘]} ${portlet.getSessionPrefJS[‘mynamespace, prefname‘]} ${portlet.setSessionPrefJS[‘prefname, value‘]} ${portlet.setSessionPrefJS[‘mynamespace, prefname, value‘]} PortletBean 生成此 JavaScript 的方法是使用 JSP 表達(dá)式語言的屬性生成機(jī)制。從技術(shù)上來說,表達(dá)式語言語句 ${portlet.getSessionPrefJS[‘mynamespace, prefname‘]} 讀作“從包含在 PortletBean 中的 GetSessionPrefJS JavaBean 中獲取名為‘mynamespace, prefname’的屬性”。PortletBean 將‘mynamespace, prefname’屬性名稱字符串解析為 Java 對(duì)象自變量數(shù)組,而不是根據(jù)屬性名稱直接查找。例如,先將腳本字符串‘mynamespace, eventname, {key:value, key2:value2}’轉(zhuǎn)換為具有兩個(gè)字符串的對(duì)象數(shù)組和一個(gè) Java 映射。然后將這些 Java 對(duì)象轉(zhuǎn)換為相應(yīng) JavaScript 字符串以包含在客戶端 JavaScript 的 document.PCC.RaiseEvent() 方法中。 這些參數(shù)字符串的語法規(guī)則如下:
有關(guān) PortletBean 生成的 JavaScript,必須注意一點(diǎn):如果使用 <portlet:group> 標(biāo)簽來設(shè)置共享名稱空間,并且沒有指定名稱空間自變量,則該名稱空間將自動(dòng)插入到生成的 JavaScript 中。將來的 Java Portlet Tools 版本將添加更多適應(yīng)性 portlet JavaScript 生成器,為執(zhí)行隨處刷新和其它高級(jí)適應(yīng)性 portlet 功能生成客戶端 API JavaScript 方法。 |
聯(lián)系客服