• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 181, 文章 - 2, 評論 - 85, 引用 - 0
            數(shù)據(jù)加載中……

            IBM WebSphere 開發(fā)者技術(shù)期刊: 使用 Rational Application Developer 和 WebSphere Application Server 來加速基于 XML 的 SOA 的 JSF 開發(fā)——第 4 部分

            本文是此系列文章的第 4 部分,該系列提出了加快基于 XML 的面向服務(wù)體系結(jié)構(gòu)(Service Oriented Architecture,SOA)應(yīng)用程序表示開發(fā)的解決方案。本文重點(diǎn)集中于利用 IBM ? Rational? Application Developer V6 和 IBM Websphere ? Portal 開發(fā) portlet。Portlet 用個(gè)人化的、管理的、再次使用的內(nèi)容提供了強(qiáng)大的呈現(xiàn)方式。本文通過分析預(yù)構(gòu)建的保險(xiǎn) portlet 應(yīng)用程序范例,描述了將 portlet 和 數(shù)據(jù)(在 portlet 內(nèi)及 portlet 間共享)結(jié)合服務(wù)數(shù)據(jù)對象(Service Data Object)使用時(shí)的配置和架構(gòu)細(xì)節(jié)。

            引言

            這個(gè)包含五部分的系列文章提出了加快基于 XML 的 SOA 應(yīng)用程序表示開發(fā)的解決方案。在該系列文獻(xiàn)的:

            • 第 1 部分 中,我們經(jīng)歷了通過使用所提供的插件集來向每個(gè)指定的 XML schema 中的服務(wù)傳遞信息的簡單 JavaServer? Faces (JSF) 應(yīng)用程序的整個(gè)開發(fā)過程。
            • 第 2 部分 中,我們增強(qiáng)了在 第 1 部分 中開發(fā)的解決方案,使之包括創(chuàng)建、更新和刪除功能,包括用本地附加的變量及基本的轉(zhuǎn)換來自定義生成 Service Data Objects(SDO)。
            • 第 3 部分 中,突出了在構(gòu)建基于 XML 的 SOA 應(yīng)用程序時(shí)用于處理 SDO 實(shí)例的不同技術(shù)。
            • 在第 4 部分中,我們將集中在基于 XML 的 SOA 應(yīng)用程序的 portlet 的開發(fā)上,會利用到貫穿于此系列的樣本保險(xiǎn)應(yīng)用程序場景。

            Portlet 提供了強(qiáng)大的管理和配置內(nèi)容傳遞方式。它們能被開發(fā)為可再次使用、封裝的表示組件,該組件可以基于終端用戶需求進(jìn)行自定義的。應(yīng)用程序服務(wù)器提供者能為他們的消費(fèi)者傳遞這些能再次使用的資產(chǎn)。然后,在管理服務(wù)器環(huán)境中,消費(fèi)者根據(jù)他們自己的需求自定義、個(gè)人化并配置這些資產(chǎn)。為提供這些可配置的資產(chǎn),服務(wù)器組件需要與這些 portlet 的內(nèi)容之間松耦合。

            出現(xiàn)在本系列前三部分的相同體系結(jié)構(gòu)非常適合 portlet 表示開發(fā),并且說明了該體系結(jié)構(gòu)能利用多種類型的呈現(xiàn)機(jī)制。本文將解決當(dāng)利用 portlet 結(jié)合 SDO 使用時(shí)所涉及到的配置和架構(gòu)問題。

            本文并不打算講解 portlet 的開發(fā),在 參考資料中使用產(chǎn)品文檔或其它在線資源時(shí)可以解決此問題。本文主要解決了對基于 XML 的 SOA 使用 SDO 時(shí),與 portlet 開發(fā)相關(guān)的問題。同時(shí),它也勾勒了創(chuàng)建 portlet 的基礎(chǔ),以及如何共享構(gòu)件、portlet 項(xiàng)目類型、portlet 狀態(tài)和 portlet 之間的數(shù)據(jù),它們是構(gòu)建 SDO 驅(qū)動的 portlet 的一些基本需求。

            在接下的文章中,您將需要 IBM Rational Application Developer V6 (以下引用時(shí)為 Application Developer)和 IBM WebSphere Portal,Version 5.1 或更新版本。本文假定讀者熟悉 Rational Application Developer 的 JSF 頁面設(shè)計(jì)器。







            安裝 XSD SDO 轉(zhuǎn)換功能

            為了安裝 XSD SDO 的轉(zhuǎn)換功能,請按照第 1 部分中的詳細(xì)步驟操作。







            XSD SDO 轉(zhuǎn)換功能的內(nèi)容

            XSD SDO 轉(zhuǎn)換功能包括用于從 XSD schema 中生成 SDO 包的構(gòu)件,以及用于將 SDO 包實(shí)例轉(zhuǎn)換到 XML 實(shí)例文件中或從 XML 實(shí)例文件中轉(zhuǎn)換出 SDO 包實(shí)例的框架組件:

            1. 創(chuàng)建 SDO 包的動作
              在 XSD 資源中的這個(gè)動作從 XSD schema 中生成了 SDO 包(如圖 1 所示)。
              圖 1. 創(chuàng)建 SDO 包
              Create SDO Package
            2. XMLTransformServiceFactory.java
              該類提供了 API 用于將 SDO 包實(shí)例轉(zhuǎn)換到 XML 實(shí)例文件中或從 XML 實(shí)例文件中轉(zhuǎn)換出 SDO 包實(shí)例。







            場景

            本文中我們將用到的場景是在第 1 部分第 2 部分中開發(fā)的保險(xiǎn)應(yīng)用程序。在該場景中:

            • 我們假設(shè) XYZ 保險(xiǎn)公司有許多已注冊的代理人。
            • 每個(gè)代理人都有許多客戶,并且每個(gè)客戶都同代理人簽訂了許多策略。
            • 保險(xiǎn)公司通過標(biāo)準(zhǔn)的 BrokerService 方案來展示代理人的服務(wù)(清單 1,圖 2),以及作為 validCodesService 模式的有效的代碼服務(wù)(清單 2,圖 3),它能檢索有效值。
            • 任何來源于代理人的通信都是符合模式定義的 XML 請求或響應(yīng)。


            清單 1. BrokerService.xsd
            												
            																		
            <?xml version="1.0" encoding="UTF-8"?>
            <xsd:schema xmlns="http:///xyz.brokerservice.ecore"
            		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            		elementFormDefault="qualified"
            		targetNamespace="http:///xyz.brokerservice.ecore">
            	<xsd:annotation>
            		<xsd:documentation xml:lang="en">
               			Broker Service Schema for xyz.com.
               			Copyright 2004 ibm.com. All rights reserved.
              		</xsd:documentation>
            	</xsd:annotation>
            	<xsd:element name="brokerService" type="brokerServiceType"/>
            	<xsd:complexType name="brokerServiceType">
            		<xsd:sequence>
            			<xsd:element minOccurs="0" name="broker" type="brokerType"/>
            			<xsd:element minOccurs="0" name="error" type="errorType"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	<xsd:complexType name="brokerType">
            		<xsd:sequence>
            			<xsd:element minOccurs="0" ref="firstName"/>
            			<xsd:element minOccurs="0" ref="lastName"/>
            			<xsd:element minOccurs="0" name="loginName" type="xsd:string"/>
            			<xsd:element minOccurs="0" name="loginPassword" type="xsd:string"/>
            			<xsd:element maxOccurs="unbounded" minOccurs="0" name="client" type="clientType"/>
            		</xsd:sequence>
            		<xsd:attribute name="brokerId" type="xsd:string" use="required"/>
            	</xsd:complexType>
            	<xsd:complexType name="clientType">
            		<xsd:sequence>
            			<xsd:element minOccurs="0" ref="firstName"/>
            			<xsd:element minOccurs="0" ref="lastName"/>
            			<xsd:element minOccurs="0" 
            					name="dateOfBirth" type="xsd:date"/>
            			<xsd:element minOccurs="0"
            					 name="currentAddress" type="addressType"/>
            			<xsd:element minOccurs="0"
            					 name="permanentAddress" type="addressType"/>
            			<xsd:element maxOccurs="unbounded" 
            					minOccurs="0" name="policy" type="policyType"/>
            			<xsd:element minOccurs="0" name="ssn"/>
            		</xsd:sequence>
            		<xsd:attribute name="clientId" 
            				type="xsd:string" use="required"/>
            		<xsd:attribute name="securityToken"
            			 type="xsd:string" use="optional"/>
            	</xsd:complexType>
            	<xsd:complexType name="addressType">
            		<xsd:sequence>
            			<xsd:element name="street" type="xsd:string"/>
            			<xsd:element name="city" type="xsd:string"/>
            			<xsd:element name="state" type="xsd:string"/>
            			<xsd:element name="zip" type="xsd:string"/>
            			<xsd:element name="country" type="xsd:string"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	<xsd:complexType name="policyType">
            		<xsd:sequence>
            			<xsd:element name="policyName" type="xsd:string"/>
            			<xsd:element name="policyStartDate" type="xsd:date"/>
            			<xsd:element name="policyEndDate" type="xsd:date"/>
            			<xsd:element name="policyAmount" type="xsd:string"/>
            			<xsd:element name="policyDescription" type="xsd:string"/>
            		</xsd:sequence>
            		<xsd:attribute name="policyId" type="xsd:string" use="required"/>
            	</xsd:complexType>
            	<xsd:complexType name="errorType">
            		<xsd:sequence>
            			<xsd:element name="errorCode" type="xsd:string"/>
            			<xsd:element name="errorDescription" type="xsd:string"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	<xsd:element name="firstName" type="xsd:string"/>
            	<xsd:element name="lastName" type="xsd:string"/>
            </xsd:schema>
            
            												
            										


            圖 2. BrokerService 方案模型
            BrokerService Schema Model

            清單 2. ValidCodesService.xsd
            												
            																		
            <?xml version="1.0" encoding="UTF-8"?>
            <xsd:schema xmlns="http:///xyz.validcodesservice.ecore"
            		xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            		elementFormDefault="qualified" 
            		targetNamespace="http:///xyz.validcodesservice.ecore">
            	<xsd:annotation>
            		<xsd:documentation xml:lang="en">
               			Valid Codes Service Schema for xyz.com.
               			Copyright 2004 ibm.com. All rights reserved.
              		</xsd:documentation>
            	</xsd:annotation>
            	<xsd:element name="validCodesService" type="validCodesServiceType"/>
            	<xsd:complexType name="validCodesServiceType">
            		<xsd:sequence>
            			<xsd:element minOccurs="0" 
            				name="stateList" type="stateListType"/>
            			<xsd:element minOccurs="0" 
            				name="policyCodeList" type="policyCodeListType"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	
            	<xsd:complexType name="stateListType">
            		<xsd:sequence>
            			<xsd:element maxOccurs="unbounded" minOccurs="0" 
            				name="state" type="stateType"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	
            		<xsd:complexType name="stateType">
            		<xsd:sequence>
            			<xsd:element name="shortName" type="xsd:string"/>
            			<xsd:element name="fullName" type="xsd:string"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	
            		<xsd:complexType name="policyCodeListType">
            		<xsd:sequence>
            			<xsd:element maxOccurs="unbounded" minOccurs="0" 
            				name="policyCode" type="policyCodeType"/>
            		</xsd:sequence>
            	</xsd:complexType>
            			<xsd:complexType name="policyCodeType">
            		<xsd:sequence>
            			<xsd:element name="shortName" type="xsd:string"/>
            			<xsd:element name="fullName" type="xsd:string"/>
            		</xsd:sequence>
            	</xsd:complexType>
            	
            </xsd:schema>
            
            												
            										


            圖 3. ValidCodes 服務(wù)方案模型
            ValidCodes Service Schema Model






            分析解決方案

            如同前面所提及的,portlet 表示比純的 JSF Web 應(yīng)用程序更加復(fù)雜。我們分析了本文所提供的解決方案,它包含一些與終端服務(wù)松耦合內(nèi)容的預(yù)構(gòu)建的 portlet。所提供的解決方案是一個(gè)包含 portlet (之后會描述)的項(xiàng)目交換文件。我們將引入包含提供 portlet 的項(xiàng)目交換文件,并解決在開發(fā)解決方案中涉及到的關(guān)鍵問題:

            1. 解決方案的內(nèi)容
            2. 創(chuàng)建 Portlet
            3. 創(chuàng)建 Portlet 視圖
            4. 導(dǎo)航鏈接
            5. Portlet 狀態(tài)
            6. 分頁
            7. Dropdown 綁定
            8. 在 portlet 視圖中傳遞數(shù)據(jù)
            9. 在 portlet 間共享數(shù)據(jù)
            10. 截取 portlet 動作
            11. 運(yùn)行 XYZ 保險(xiǎn) portlet 項(xiàng)目 .

            1. 解決方案內(nèi)容

            將項(xiàng)目交換 xsd_sdo_soa_xml_sample.zip 下載文件導(dǎo)入到 Application Developer 工作區(qū)中。結(jié)果,下列項(xiàng)目將導(dǎo)入進(jìn)來(圖 4):

            1. XYZInsuranceEAR: 企業(yè)應(yīng)用程序項(xiàng)目,它包括作為模塊或?qū)嵱贸绦虻乃衅渌?xiàng)目。
            2. XYZInsurancePortlet: 用所有現(xiàn)有的 portlet 和 JSF JSR 的 JSR 168 portlet 項(xiàng)目。該項(xiàng)目的 WebContent 文件夾包括 BrokerService.xsd 和 ValidCodesService.xsdschema, 并且在 Schema 文件夾中含有樣本數(shù)據(jù)文件。為了簡單起見,本例中 SDO 包已經(jīng)創(chuàng)建并且是門戶項(xiàng)目的一部分。
            3. XYZInsuranceService: 包含實(shí)現(xiàn)代理人服務(wù)和有效代碼服務(wù)的 Java 類。服務(wù)裝載并發(fā)送了與服務(wù)方法請求相對應(yīng)的 XML 響應(yīng)。提供此基本實(shí)現(xiàn)來模擬服務(wù)行為。它的實(shí)現(xiàn)超出了文章介紹的范圍。
            4. XYZInsuranceServiceProxy: 包括用于調(diào)用代理人服務(wù)的 ServiceProxy 的基本實(shí)現(xiàn)。


            圖 4. 導(dǎo)入的項(xiàng)目交換范例
            導(dǎo)入的項(xiàng)目交換范例

            在導(dǎo)入項(xiàng)目交換所需要的庫中,emf.jar 同 xsdsdotransform.jar 一起被加上。這提供了所需級別的 Eclipse Modeling Framework (EMF) 和 Service Data Object (EMF-SDO) 運(yùn)行庫 (圖 5)。本文所需要的 XML-SDO 轉(zhuǎn)換插件運(yùn)行時(shí)版本并沒有與 WebSphere Portal V5.0.2.x or V5.1 封裝在一起。 XSD SDO 轉(zhuǎn)換功能至少需要 EMF-SDO 的 2.1 版本。您將有必要手動將支持的 JAR 添加到針對這些 WebSphere Portal 版本的項(xiàng)目中。您可獲得所需的 JAR,它們可在Eclipse Modeling Framework Web 站點(diǎn)中下載,或者在 Websphere Application Server V6.0 運(yùn)行時(shí)文件夾中使用 emf.jar 文件:

            • commonj.sdo.jar
            • common.resources.jar
            • common.jar
            • xsd.resources.jar
            • xsd.jar
            • ecore.jar
            • ecore.change.jar
            • ecore.xmi.jar


            圖 5. 添加 EMF-SDO 運(yùn)行時(shí)
            EMF-SDO runtime addition

            導(dǎo)入的 Web 項(xiàng)目 XYZInsurancePortlet 是 Portlet JSR 168 項(xiàng)目。當(dāng)創(chuàng)建一個(gè)項(xiàng)目應(yīng)用程序時(shí),必須選擇 portlet 項(xiàng)目的類型。Application Developer 對下列內(nèi)容支持創(chuàng)建 portlet 項(xiàng)目:

            • IBM portlet API 作為 "Portlet Project"
            • JSR 168 portlet API 作為 "Portlet Project (JSR 168)"

            符合 JSR 168 規(guī)范的 portlet 可以部署到任何符合 JSR 168 的門戶,并為 portlet 應(yīng)用程序提供可移植性,而不是限制在WebSphere Application Server 上。選擇一個(gè)應(yīng)用服務(wù)提供者來將相同的應(yīng)用程序部署到多個(gè)客戶端時(shí),跨平臺需求可能是一個(gè)關(guān)鍵的因素。

            Application Developer 支持基于 JSR 168 規(guī)范的 Faces portlet 開發(fā)。Snippets 支持普通任務(wù),象編碼名稱空間、改變窗口模式、行最小化和最大化等等。然而,在 JSR 168 中不支持 click-to-action 合作行為和 portlet 消息。

            對于新的 portlet,當(dāng)支持項(xiàng)目類型的功能足以滿足 portlet 的需求時(shí),或者當(dāng) portlet 期望作為 Remote Portlets (WSRP)服務(wù)的 Web 服務(wù)公布時(shí),考慮使用 JSR 168 portlet。 JSR 168 portlet API 的一些通用標(biāo)記(例如,<namespace> 和 <actionURL>)不能用在 JSR 168 項(xiàng)目中的 Faces portlet JSP 文件中(當(dāng)創(chuàng)建這些項(xiàng)目時(shí)請參考 Application Developer 幫助,以便了解這些項(xiàng)目類型間的區(qū)別)。

            Application Developer 可支持 WebSphere Portal V5.0.2.x (僅僅是 Windows?) 和 WebSphere Portal V5.1 的單元測試環(huán)境。

            導(dǎo)入的項(xiàng)目包括共享 JSF JSP 的多個(gè) portlet, 并對 portlet 通信使用 property 代理。以下羅列的是對 portlet 的描述和它們相關(guān)的視圖。

            樣本 portlet 視圖(作為 JSF JSP )

            • BrokerSummary: 發(fā)送代理人概要請求(brokerSummaryRequest.xml),并接收包含代理人客戶和他們的策略(brokerSummaryResponse.xml)的響應(yīng)。XML 響應(yīng)在會話管理頁面 root wrapper bean (BrokerDetailRoot),它用來在頁面的控制面板中提供數(shù)據(jù)。
            • BrokerSummaryNew: 同 BrokerSummary 相似,當(dāng)添加新的策略時(shí)展示出來。
            • BrokerDetail:發(fā)送代理人詳細(xì)請求(brokerDetailRequest.xml),并接收包含所有代理人客戶和他們的策略(brokerDetailResponse.xml)的響應(yīng)。XML 響應(yīng)在會話管理頁面 root wrapper bean (BrokerDetailRoot),它用來在頁面的控制面板中提供數(shù)據(jù)。
            • AddPolicy: 通過發(fā)送請求能為現(xiàn)存客戶添加新的策略,并且為請求變化的成功或失敗接收 XML 響應(yīng)(addPolicyResponse.xml)。The XML responses are processed in a page root wrapper bean (AddPolicyRoot) that is used to process the updates along with the session managed page root wrapper bean (BrokerDetailRoot)。
            • SearchPolicy: 在下拉菜單中選擇最大的策略數(shù)量,該菜單用 validCodesService 中的靜態(tài)清單值和動態(tài)清單狀態(tài) populated。此視圖展示了靜態(tài)和動態(tài)清單驅(qū)動下拉控制的使用。所選的值被傳遞到 SearchPolicyResult 頁面。
            • SearchPolicyResult: 對基于最大數(shù)量參數(shù)(policySearchRequest.xml)的策略查找發(fā)送請求,并用匹配策略(policySearchResult.xml)接收響應(yīng)。響應(yīng)在頁面根 bean 包裝器(SearchPolicyResultRoot)中運(yùn)行,它運(yùn)行(policySearchResult.xml)和提供結(jié)果。
            • BrokerSummaryHelp: 對 BrokerSummary portlet 提供幫助。

            樣本 portlet

            • BrokerSummaryPortlet: 主要的視圖是 BrokerSummary。通過調(diào)用服務(wù),更新命令來更新內(nèi)容。
            • BrokerDetailPortlet: 主要視圖是 BrokerDetail ,并且與 AddPolicy 鏈接。當(dāng)添加一個(gè)新的策略時(shí),BrokerSummaryPortlet 被通知更新有變化的概要內(nèi)容,并且展示 BrokerSummaryNew 視圖。利用財(cái)產(chǎn)代理人作為 AddPolicyDataMessage,多個(gè)數(shù)據(jù)傳遞到 portlet。
            • SearchPolicyPortlet: 主要的視圖是 SearchPolicy,并且與 SearchPolicyResult 鏈接。

            2.創(chuàng)建 Portlet

            創(chuàng)建新的 JSR 168 portlet:

            1. 在 Application Developer 中,打開 New Portlet 對話框(圖 6)。
            2. 選擇 portlet Project 名稱,XYZInsurancePortlet,分配 Default 的名稱前綴BrokerSummaryPortlet,并確定新的 portlet 作為Faces portlet (JSR 168),因此 添加 Faces portlet 框架庫到此項(xiàng)目中(如果它們已經(jīng)不存在)。
              圖 6. 創(chuàng)建新的 portlet
              Create a new portlet
            3. 接著,確認(rèn) Portlet 名稱,選擇默認(rèn)的 Internationalization Locale,并選擇Change the code generation options 改寫默認(rèn)名稱,如圖 7 所示。
              圖 7.設(shè)置 Portlet
              Portlet settings
            4. 作為上述步驟的結(jié)果,將生成圖 13-10 中展示的構(gòu)件。
              圖 8. 生成的構(gòu)件
              Generated artifacts

            3. 創(chuàng)建 Portlet 視圖

            利用 New Faces JSP File 對話框 (圖 9)為above羅列的每一個(gè)樣本 portlet 視圖創(chuàng)建 Faces JSP。對每一個(gè) JSP,確保為 Model 字段指定Portlet 。這樣能保證合適的 portlet 標(biāo)記符被初始化,并用于 JSF 表示中。完成時(shí),新的 Faces JSP 將出現(xiàn)在項(xiàng)目中,如同他們在圖 10 所做的那樣。


            圖 9. 創(chuàng)建 Create Faces JSP
            Create Faces JSPs

            圖 10 . 創(chuàng)建 Faces JSP
            Create Faces JSPs

            Application Developer 利用所提供的易于使用的編輯器,為 portlet 配提供置部署的能力,正像它為 EJB 或者 Web 項(xiàng)目所做的那樣。您能利用編輯器修改每一個(gè) portlet 的配置(優(yōu)于修改作為源的 portlet 部署描述符),舉個(gè)例子,可改變在前面的章節(jié)中,通過為不同的模式添加初始化參數(shù)而創(chuàng)建的 portlet 視圖,比如視圖、編輯、幫助和配置。(圖 12)


            圖 11. 更新 portlet 部署描述符
            Update portlet deployment descriptor

            圖 12. 更新 portlet 部署描述符
            Update portlet deployment descriptor

            4. 導(dǎo)航鏈接

            任何多頁表示均需要從一個(gè)頁面到另外一個(gè)頁面的導(dǎo)航訪問,并且由 portlet 提供導(dǎo)航控制,這就簡化了導(dǎo)航的開發(fā)。可添加導(dǎo)航鏈接到使用鏈接控制的 portlet 內(nèi),但是,在導(dǎo)航鏈接控制中提供 URL 值時(shí),需要進(jìn)行特殊的考慮:在我們的場景中,鏈接 URL 定義為 "/BrokerSummary.jsp".而沒有點(diǎn)(.)。這與開發(fā)純的 JSF Web 應(yīng)用程序頁面不同,它在導(dǎo)航鏈接中需要點(diǎn)(.)。(今后本產(chǎn)品的版本中此要求可能去掉)


            圖 13. 添加鏈接
            Link addition

            5. Portlet 狀態(tài)

            作為一種強(qiáng)大的內(nèi)容傳遞機(jī)制,portlet 表示提供了一種在同一表示頁面中配置 portlet 狀態(tài)的方法。獨(dú)立 portlet 的狀態(tài)能被最大化或最小化,因此為用戶感興趣的內(nèi)容提供了更人性化的視圖。為了實(shí)現(xiàn)它,portlet 呈現(xiàn)被分為兩個(gè)階段:動作階段和移交階段: As a powerful content delivery mechanism, portlet presentations provide a way to configure the state of the portlet within the same presentation page. The state of individual portlets can either be maximized or minimized, thus providing the user with a more personalized view of the content of interest. To achieve this, portlet presentation delivery is divided into two phases: an action phase and a render phase:

            • 當(dāng) portlet 表示頁面被請求時(shí),portlet 進(jìn)入 移交階段,并展示其內(nèi)容。
            • 當(dāng)在 portlet 上調(diào)用任何動作時(shí),portlet 進(jìn)入 動作階段,與 portlet 相對應(yīng)的動作原理被調(diào)用。

            在開發(fā) portlet 中需要特殊考慮的動作對移交階段里,可獲得什么樣的 API 有其局限性。創(chuàng)建請求和響應(yīng)對象,并且每個(gè)階段獲得不同的內(nèi)容。圖 14 中的代碼樣本展示了,對 JSR 168 portlet 項(xiàng)目,當(dāng) portlet 處于工作階段時(shí),如何利用 ActionResponse 改變窗口狀態(tài)。就像在我們的場景中,如果終端用戶正瀏覽所有客戶機(jī)的策略細(xì)節(jié)并添加了新的策略時(shí),他可能將 BrokerDetailPortlet 最大化來獲得更好的利用視圖區(qū)域的用戶體驗(yàn)。BrokerDetail.jsp 頁面展示了使用 API 改變窗口狀態(tài)。


            圖 14. 改變窗口狀態(tài)的代碼片斷
            Code snippet for changing window state

            6. 分頁

            在可管理的組中表示一大組數(shù)據(jù),提供每頁數(shù)據(jù)的子集是經(jīng)常的需求。在 JSF 頁面 中提供尋呼機(jī)控制在這些數(shù)據(jù)組間的標(biāo)記頁碼。在 Faces JSP 頁面同時(shí)使用尋呼機(jī)功能和 click-to-action 功能時(shí)要進(jìn)行特殊的考慮。在這樣的案例中,使用簡單的尋呼機(jī)或轉(zhuǎn)到尋呼機(jī)控制器,就像圖 15 展示的那樣,而不是 高級的或 Web 類型尋呼機(jī)控制器,這些目前不能被 WebSphere Portal 支持。


            圖 15. 尋呼機(jī)控制器
            Pager controls

            7. Dropdown 綁定

            Dropdown 通常用在表示中,無論它是 portlet 或僅是 JSF Web 頁面。 Dropdown的值要么被服務(wù)調(diào)用動態(tài)尋回,要么處于用控制器的靜態(tài)定義清單中。在我們的場景中,用的是 portlet 視圖的靜態(tài)清單。SearchPolicyPortlet 提供在 Policy amount 的基礎(chǔ)上尋找策略的方法,并且在 SearchPolicy.jsp 的 dropdown 中提供了策略值的靜態(tài)清單,就像下圖展示的那樣:


            圖 16. 靜態(tài)清單
            Static list

            圖 17. 靜態(tài)清單 dropdown
            Static list dropdown

            8. 在 portlet 視圖間傳遞數(shù)據(jù)

            總有必要在 portlet 的視圖間從一個(gè)視圖向另一個(gè)視圖傳遞數(shù)據(jù)。可利用請求或會話傳遞數(shù)據(jù),或者您甚至能在表格上定義隱藏變量傳遞數(shù)據(jù)。例如:

            1. 在 BrokerDetail.jsp 頁面中(圖 18),利用請求參數(shù)傳遞客戶機(jī) Id 給 AddPolicy.jsp 頁面(圖 19)
            2. 請求變量的值在頁面 bean 根包裝器 AddPolicyRoot 中作為 selectedClientId 屬性被高速緩存起來。
            3. 表格上的隱藏變量(圖 20)用于在頁面上不同命令動作間保持其值。
            4. 通過把 getText5 變?yōu)楣驳模珺rokerDetail.java 頁面代碼中的 text5 屬性展現(xiàn)在頁面數(shù)據(jù)中。
            5. 在 SearchPolicy.jsp 頁面中,將 dropdown 中選擇的值作為請求參數(shù)傳遞到 portlet 的下一個(gè)頁面中(圖 21 和 22)。


            圖 18. 在 BrokerDetail.jsp 中利用請求參數(shù)在 portlet 視圖間傳遞數(shù)據(jù)
            Passing data within portlet views using request parameter in BrokerDetail.jsp

            圖 19. 在 AddPolicy.jsp 中尋回頁面負(fù)載上的請求參數(shù)
            Retreiving request parameter on page load in AddPolicy.jsp

            圖 20. 利用 AddPolicy.jsp 的隱藏變量超高速緩存 portlet 視圖間的數(shù)據(jù)
            Caching data within portlet views using hidden variables in AddPolicy.jsp

            圖 21. 在 SearchPolicy.jsp 中傳遞數(shù)據(jù)作為請求屬性
            Passing data as request attribute in SearchPolicy.jsp

            圖 22. 在負(fù)載上的 SearchPolicyResult.jsp 中尋回請求屬性
            Retreiving request attribute in SearchPolicyResult.jsp on load

            9. 在 portlet 間共享數(shù)據(jù)

            在前面的章節(jié)中,展示了如何在單個(gè)的 porlet 視圖中共享數(shù)據(jù)。在不同的 protlet 間共享數(shù)據(jù)的需求也逐漸提升起來。就像在我們的場景中,在 BrokerDetailPortlet 中使用 AddPolicy 視圖添加新的策略時(shí),BrokerSummaryPortlet 中的 BrokerSummary 視圖應(yīng)當(dāng)為用戶更新來反應(yīng)新加的策略。為 BrokerSummary 視圖服務(wù)的 bean 應(yīng)當(dāng)從服務(wù)中請求新的數(shù)據(jù)。為了與 BrokerSummaryPortlet 通信,需要從 BrokerDetailPortlet 傳遞消息或者參數(shù)到 BrokerSummaryPortlet,因此要在 portlet 間創(chuàng)建需求共享數(shù)據(jù)。

            共享數(shù)據(jù)的 portlet 被稱為 cooperative portlets。在 portlet 間共享數(shù)據(jù)能從多種途徑獲得:

            本文提供的解決方案示例了在 portlet 間利用單個(gè)屬性與多個(gè)數(shù)據(jù)屬性通信的property代理人機(jī)制:

            • 在 AddPolicy.jsp 的 doAddPolicy 動作中,無論何時(shí)在 BrokerDetailPortlet 中添加新的策略時(shí),RefreshView、 NextView 和 WindowState 屬性作為請求屬性 (NextViewData) 傳遞給 BrokerSummaryPortlet。
            • 在 BrokerSummaryPortlet 的 brokerSummary.jsp 視圖中調(diào)用 doUpdateView 動作,并且為多個(gè)屬性分析 NextViewData 。
            • 僅僅當(dāng) RefreshView 屬性正確并且 NextView 屬性確定展示視圖的時(shí)候,才用 BrokerService 的數(shù)據(jù)更新Java bean。
            • 窗口的狀態(tài)的確定基于 WindowState 屬性。

            這些數(shù)據(jù)示例了數(shù)據(jù)傳遞時(shí) property 代理人的配置:

            1. 啟用包含視圖的源 portlet 使之能傳遞數(shù)據(jù)。(圖 23)
              圖 23. 啟用源 portlet
              Enable source portlet
            2. 指定用于涉及數(shù)據(jù)傳遞的數(shù)據(jù)類型名稱。當(dāng)現(xiàn)存的數(shù)據(jù)類型被創(chuàng)建時(shí),您也可以選擇其清單。
            3. boundTo 屬性指定了用于指定所需傳遞數(shù)據(jù)的機(jī)制。
            4. 結(jié)果,一個(gè) <SourcePortlet>.wsdl 文件在 webcontent\wsdl 文件夾中生成,該文件夾包含數(shù)據(jù)類型定義作為 WSDL 語法。
              圖 24. 源 portlet 規(guī)范
              Source portlet specification
            5. 確信動作名稱和標(biāo)題在為源 portlet 規(guī)范產(chǎn)生的 WSDL 中進(jìn)行了定義。當(dāng)指定連線的時(shí)候(之后再描述),標(biāo)題值用來確定動作。如果這些值不存在,請?zhí)峁┏鰜怼?
              <operation name="BrokerDetailPortletportlet">
              	<portlet:action name="UpdateView" caption="Update View" type="standard" />
              	<output>
              		<portlet:param name="NextViewData"
              			partname="NextViewData_Output" boundTo="request-attribute"
              caption="NextViewData"/> </output> </operation>

            6. 在需要傳遞參數(shù)的動作上,額外的 request-parameter com.ibm.portal.propertybroker.action 需要為被調(diào)用的動作進(jìn)行定義。此處用到的名稱與在源 portlet WSDL 規(guī)范中指定的名稱相同。Property 代理人服務(wù)用參數(shù)來調(diào)用指定的動作。
              圖 25. 傳遞源參數(shù)
              Pass source parameters
            7. 在容器中可設(shè)置數(shù)據(jù)作為在源 portlet 規(guī)范中 boundTo 屬性的指定值。在本例中,數(shù)據(jù)在 RequestScope 中設(shè)置為調(diào)用動作代碼的請求屬性。
              public String doAddPolicyAction(){
              			this.getVarAddPolicyRootBean().addPolicy
              		(this.getVarBrokerDetailRootBean().getBrokerServiceRoot());
              	this.sessionScope.remove("varBrokerDetailRootBean");
              	setNextViewData();
              	return "addPolicy";
              }
              
              public void setNextViewData(){
              	//newViewOutcomeName:RefreshView:WindowState
              	String nextViewData = "newView:true:maximized";
              	this.getRequestScope().put("NextViewData", nextViewData);
              }
              

            8. 啟用包含即將收到傳遞數(shù)據(jù)的視圖的目標(biāo) portlet。
              圖 26. 啟用目標(biāo) portlet
              Enable target portlet
            9. 瀏覽在其上調(diào)用動作和傳遞指定數(shù)據(jù)的視圖。目標(biāo)文件中的 boundTo 屬性可與源 portlet 已經(jīng)指定的內(nèi)容不同;這就定義了發(fā)送傳遞數(shù)據(jù)的容器。參數(shù)或動作的名稱也可與在源 portlet 指定的名稱不同。
              圖 27. 瀏覽動作
              Browse the action

              圖 28. 目標(biāo) portlet 規(guī)范
              Target portlet specification
            10. 為目標(biāo) portlet 規(guī)范在 webcontent\wsdl 文件夾中生成了 WSDL,該規(guī)范定義了調(diào)用的動作和收到的數(shù)據(jù)。定義portlet (之后將在中描述) 之間的連線時(shí)用到標(biāo)題名稱。按照由 boundTo 屬性指定的容器,指定的 portlet 參數(shù)能從視圖調(diào)用的動作中尋回。在本例中,可以從請求作用屬性中尋回 NextViewData。
              <operation name="BrokerDetailPortletportlet">
              	<portlet:action name="UpdateView" caption="Update View" type="standard" />
              	<output>
              		<portlet:param name="NextViewData"
              			partname="NextViewData_Output" boundTo="request-attribute"
              caption="NextViewData"/> </output> </operation>

            11. 在 BrokerSummary.java 中,NextViewData 能從請求作用區(qū)域?qū)傩阅莾簩せ睾图庸ぁ?
              public String doUpdateViewAction(){
              	return processNextViewData();
              }
              
              public String processNextViewData(){
              	String newViewOutcome="";
              	//newViewOutcomeName:RefreshView:WindowState
              	String nextViewData = (String)this.getRequestScope().get("NextViewData");
              	if(nextViewData != null && nextViewData.length() > 0){
              		String[] params = nextViewData.split(":");
              		if(params != null && params.length > 0){
              			newViewOutcome = params[0];
              			if(params.length > 1){
              				if(Boolean.getBoolean(params[1]) == true){
              					//remove the key to get updated data from service
              					this.getSessionScope().remove
              						("varBrokerSummaryRootBean");
              				}
              				if(params.length > 2){
              					//set the window state
              					setWindowState(params[2]);
              				}
              			}
              		}
              	}else{
              		this.getSessionScope().remove("varBrokerSummaryRootBean");
              		return "view";
              	}
              	return newViewOutcome;
              }
              
              public void setWindowState(String windowState) {
              	ActionResponse actionResponse = (ActionResponse)
              		getFacesContext().getExternalContext().getResponse();
              	try {
              		if(windowState == "maximized"){
              			actionResponse.setWindowState(WindowState.MAXIMIZED);
              		}
              		else if(windowState == "minimized"){
              			actionResponse.setWindowState(WindowState.MINIMIZED);
              		}
              		else if(windowState == "normal"){
              			actionResponse.setWindowState(WindowState.NORMAL);
              		}
              	}
              	catch (WindowStateException e) {
              		logException(e);
              	}
              }

            您也能使用傳遞技術(shù)到共享多個(gè)屬性的復(fù)雜數(shù)據(jù),就像在范例中那樣,在合作的 portlet 間傳遞復(fù)雜的數(shù)據(jù)。

            10.截取 portlet 動作

            在前面的例子中,在目標(biāo) portlet 正展示的 portlet 視圖上調(diào)用動作。一旦視圖從 brokerSummary 變到 brokerSummaryNew,任何新的策略添加無法在 brokerSummaryPortlet 中更新。另一個(gè)應(yīng)用程序需求可能是因?yàn)樵?portlet 對目標(biāo) portlet 上正展示的視圖不了解。在這樣的案例中,目標(biāo)動作代碼不能放置在視圖中。在呈現(xiàn) 現(xiàn)存的視圖之前需要再細(xì)分 portlet 類,也需要截取動作。從傳遞到 portlet 動作那兒的數(shù)據(jù)里定義的視圖名稱能設(shè)置成視圖,示例如下:

            1. 在 <TargetPortlet>.wsdl 文件中,定義動作名稱為 UpdateView。這個(gè)名稱用來截取 portlet 子集中的動作。
              <operation name="BrokerSummaryPortletportlet">
              	<portlet:action
              		name="UpdateView"
              		type="standard" caption="Update View" description="Update View Action" />
              	<input>
              		<portlet:param name="NextViewData"
              			partname="NextViewData_Input" boundTo="request-attribute" />
              	</input>
              </operation>

            2. 在為 portlet 創(chuàng)建的子集中,為動作名稱截取動作并檢查 com.ibm.portal.propertybroker.action 請求參數(shù)。如果動作名稱是 UpdateView,為視圖名稱更新會話參數(shù) com.ibm.faces.portlet.page.view 作為從動作參數(shù)尋回?cái)?shù)據(jù)的定義。
              public void processAction(ActionRequest request, ActionResponse response)
              		throws PortletException {
              
              	String actionName = (String)request.getParameter("com.ibm.portal.propertybroker.action");
              	if (actionName != null && actionName.equals("UpdateView")) {
              
              		// passed value is something like 'viewName1:true:maximized' in the parameter
              		String nextViewData= (String) request.getAttribute("NextViewData");
              				if(nextViewData != null && nextViewData.length() > 0){
              			String viewName = null;
              			int i = nextViewData.indexOf(':');
              			if (i >= 0) viewName = nextViewData.substring(0, i);
              
              			if(viewName  != null){
              				//change the portletView to be displayed
              				request.getPortletSession().setAttribute
              				("com.ibm.faces.portlet.page.view", viewName );
              			}
              					}
              	}
              

            3. 在期待 NextViewData 數(shù)據(jù)的視圖頁面代碼中,在視圖中尋回參數(shù)作為 RequestScope 參數(shù)并在目標(biāo) portlet 中展示。您可以選擇利用執(zhí)行基于數(shù)據(jù)變化的原理寫普通的實(shí)用程序類,以便跨越視圖時(shí)它能得以再次利用。
              public BrokerSummaryRoot getVarBrokerSummaryRootBean() {
              	if (varBrokerSummaryRootBean == null) {
              		varBrokerSummaryRootBean = (BrokerSummaryRoot) getFacesContext()
              			.getApplication().createValueBinding(
              				"#{varBrokerSummaryRootBean}").getValue(
              				getFacesContext());
              	}
              	String nextViewData= (String) request.getAttribute("NextViewData");
              	//process data
              	return varBrokerSummaryRootBean;
              }
              

            11. 運(yùn)行 XYZInsurance portlet 項(xiàng)目

            1. 因?yàn)?EMF 的不同運(yùn)行時(shí)版本必須有 XSD SDO 轉(zhuǎn)換功能才能使用,所以部署在 WebSphere Portal V5.0.2.x 或 V5.1 上的利用轉(zhuǎn)換功能的應(yīng)用程序需要用 PARENT_LAST 類加載器策略和 APPLICATION WAR 類加載器策略隔離進(jìn)行設(shè)置。圖 29 展示了用于設(shè)置此類加載器配置的 WebSphere Portal 配置中的章節(jié)。如果沒有,可從全球類途徑登陸到 portal 服務(wù)器提供的 EMF 框架工作的更老點(diǎn)的版本。這個(gè)版本與需要 XSD SDO 轉(zhuǎn)換功能生成的 SDO 的那個(gè)不相容,因此可能引起應(yīng)用程序的運(yùn)行時(shí)失敗。
              圖 29. WebSphere Portal 應(yīng)用程序類加載器
              WebSphere Portal application classloader configuration
            2. 為配置統(tǒng)一測試環(huán)境(UTE),用選擇的 Test environment 安裝選項(xiàng)安裝 WebSphere Portal V5.1。您工作空間安裝的運(yùn)行時(shí)中的 WebSphere Portal 存根應(yīng)該指向安裝的 portal 服務(wù)器 UTE 位置。結(jié)果,WebSphere Portal V5.1 測試環(huán)境將作為目標(biāo)服務(wù)器運(yùn)行時(shí)的選擇展示出來(圖 30)。目標(biāo)為此存根的任何項(xiàng)目作為運(yùn)行時(shí)時(shí)將被配置來使用這個(gè)測試環(huán)境。保證定好對 WebSphere Portal V5.1 服務(wù)器的 JSR 168 portlet 項(xiàng)目目標(biāo)來使用合作 portlet。
              圖 30. 作為檢測環(huán)境的 WebSphere Portal V5.1 存根配置
              WebSphere Portal V5.1 stub configuration as test environment
            3. 因?yàn)槲覀兊膱鼍笆褂?property 代理實(shí)現(xiàn) portlet 間的數(shù)據(jù)共享,因此附加的配置步驟(創(chuàng)建 portlet 線路,在下一步中作為示例)需要用來啟用 portlet 通信。利用 portal 服務(wù)器管理控制臺創(chuàng)建和配置線路。在 portal 服務(wù)器管理控制臺中啟用線路配置,確保在您在 WebSphere Portal 配置的 Portal Options 中檢查為 portal 管理和自定義啟用基礎(chǔ) portlet。(圖 31)
              圖 31. Portal 選項(xiàng)
              Portal options
            4. 在 portlet 間為 property 代理連線 portlet,服務(wù)器啟動后每次執(zhí)行下列步驟:
            5. 選擇 XYZInsurance 應(yīng)用程序,右鍵點(diǎn)擊并選擇 Run On Server。圖 35、36 和 37 展示了出現(xiàn)在解決方案中的所有 portlet。
              圖 35. 簡明的 portlet
              Summary portlet

              圖 36. 詳細(xì)的 portlet
              Detail portlet

              圖 37. 尋找 portlet
              Search portlet






            結(jié)束語

            本系列文章的第 4 部分致力于分析示例應(yīng)用程序場景,該場景使用基于 XML 的 SOA 松耦合的 portable JSR 168 portlet 開發(fā)。也描述了在 WebSphere Portal 的配置中涉及到的為必需的 EMF 運(yùn)行時(shí)區(qū)別的問題。本文集中在 portlet 視圖和 portlet 間的共享數(shù)據(jù)上,并描述了通過 property 代理人用單個(gè) property 在共享多個(gè)數(shù)據(jù)屬性涉及到的步驟。

            第五部分將討論為使用 XSD SDO 轉(zhuǎn)化特性的基于 XML 的 SOA 本地化 JSF 和 portlet 應(yīng)用程序,并且將定位基于優(yōu)選的區(qū)域顯示本地化的靜態(tài)和動態(tài)內(nèi)容。








            下載

            描述 名字 大小 下載方法
            Download file 1 xsd_sdo_soa_xml_sample.zip 4.8 MB ?FTP|HTTP
            Download file 2 xsdsdotransform-feature.zip 52 KB ?FTP|HTTP

            posted on 2006-04-17 03:30 wsdfsdf 閱讀(481) 評論(0)  編輯 收藏 引用 所屬分類: 技術(shù)文章

            久久精品成人免费观看97| 久久久亚洲AV波多野结衣| 7777久久久国产精品消防器材 | 久久精品国产亚洲AV无码偷窥| 国产午夜精品久久久久九九| 亚州日韩精品专区久久久| 精品国产日韩久久亚洲| 亚洲欧美一区二区三区久久| 久久久久亚洲精品日久生情 | 囯产精品久久久久久久久蜜桃 | 国产精品国色综合久久| 国产精品久久久久久一区二区三区| 久久综合久久久| 久久久久人妻精品一区三寸蜜桃| 久久精品国产亚洲αv忘忧草| 久久天天躁狠狠躁夜夜网站| 国产精品久久久久久| 欧美日韩精品久久久久| 久久99亚洲网美利坚合众国| 久久久久免费视频| 久久精品99久久香蕉国产色戒 | 国产成人精品久久一区二区三区| 久久国产免费观看精品3| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 欧美精品丝袜久久久中文字幕 | 国产午夜精品理论片久久影视| 国产免费久久精品丫丫| 一本久久a久久精品综合香蕉| 国产精品久久免费| 伊人久久大香线蕉av不变影院| 亚洲欧美日韩精品久久| 中文字幕无码精品亚洲资源网久久 | av国内精品久久久久影院| 亚洲欧美国产日韩综合久久| 久久夜色tv网站| 国产精品免费福利久久| 亚洲熟妇无码另类久久久| 久久九九免费高清视频| 99精品久久精品一区二区| 精品久久久久久久久免费影院| 亚洲国产成人乱码精品女人久久久不卡|