OpenDoc版權(quán)說(shuō)明:
本文檔版權(quán)歸原作者所有。
在免費(fèi)、且無(wú)任何附加條件的前提下,可在網(wǎng)絡(luò)媒體中自由傳播。
如需部分或者全文引用,請(qǐng)事先征求作者意見(jiàn)。
如果本文對(duì)您有些許幫助,表達(dá)謝意的最好方式,是將您發(fā)現(xiàn)的問(wèn)題和文檔改進(jìn)意見(jiàn)及時(shí)反饋給作者。當(dāng)然,倘若有時(shí)間和能力,能為技術(shù)群體無(wú)償貢獻(xiàn)自己的所學(xué)為最好的回饋。
序
隨著信息化建設(shè)的深入,Portal 門戶已經(jīng)成為新型辦公環(huán)境的一個(gè)重要組成部分。 Portal所提供的單點(diǎn)登錄、權(quán)限控制、個(gè)性化定制、內(nèi)容集成、文件管理等獨(dú)特的功能, 已經(jīng)大大占據(jù)公眾的眼球,并在信息集成和消除信息孤島方面發(fā)揮了重要的左右。
隨著Portal技術(shù)的成熟,以MyNestcape、MyYahoo、MSN-Space等為代表大型網(wǎng)站也較多的采用Portal架構(gòu)來(lái)實(shí)現(xiàn)個(gè)性化的內(nèi)容聚合和定制,以實(shí)現(xiàn)靈活的擴(kuò)展的服務(wù)策略。
Liferay Portal作為一個(gè)開(kāi)源的Portal項(xiàng)目,利用Hibernate、Struts、Spring等開(kāi)源框架,實(shí)現(xiàn)了JCP JSR168規(guī)范中提出的Portal功能,在開(kāi)源Portal系統(tǒng)中有比較典型的代表性。
本
文從Liferay Portal的架構(gòu)入手,詳細(xì)講解Portal的用戶策略、內(nèi)容布局、桌面和品質(zhì)的要素,引導(dǎo)讀者完成Liferay
Portal初步的二次開(kāi)發(fā),在Liferay Portal上定制自己的Portlet。Liferay
Portal程序框架和源碼分析不在本文的討論范圍。
目錄
第一部分 Liferay Portal 架構(gòu)解析
第一章 Liferay Portal
第一節(jié) Portal規(guī)范
1.1.1 JSR168
1.1.2 WSRP
第二節(jié) 什么是Portal
1.2.1 Portal 服務(wù)器
1.2.2 Portlet容器
第三節(jié) 什么是Portlet
1.3.1 Portlet
1.3.2 Portlet與Servlet的關(guān)系
1.3.3 Portlet的生命周期
第四節(jié) Liferay Portal工作原理
1.4.1 Portlet 樣式以及窗口狀態(tài)
1.4.2 Portal頁(yè)面
第二章Liferay Portal的使用
第一節(jié) Liferay Portal安裝
第二節(jié) Liferay Portal的用戶策略
2.2.1 定義用戶
2.2.2 添加用戶
2.2.3 修改用戶
2.2.4 定義用戶組
2.2.5 新增、重命名用戶組
2.2.6 修改用戶組
2.2.7 定義角色
2.2.8 新增、重命名角色
2.2.9 修改用戶組角色
2.2.10 定義Portlet的角色
第三節(jié) Liferay Portal內(nèi)容和布局
2.3.1 什么是布局
2.3.2 什么是內(nèi)容
2.3.3 內(nèi)容布局與Portlet的關(guān)系
2.3.4 選擇內(nèi)容和布局
第四節(jié) Liferay Portal的桌面
2.4.1 什么是桌面
2.4.2 定義個(gè)性化的桌面
第五節(jié) Liferay Portal的品質(zhì)
2.5.1 什么是品質(zhì) 30
2.5.2 品質(zhì)和Portlet、Portal的關(guān)系
2.5.3 定義個(gè)性化的品質(zhì)
第六節(jié) Liferay Portal的部署描述文件
2.6.1 web.xml
2.6.2 portlet.xml
2.6.3 liferay-Portlet.xml
2.6.4 liferay-display.xml
2.6.5 liferay-layout-templates.xml
2.6.7 liferay-look-and-feel。xml
第二部分 Liferay Portal 二次開(kāi)發(fā)
第三章 開(kāi)發(fā)自己的Portlet
第一節(jié) 重要的基類:GenericPortlet
第二節(jié) Portlet標(biāo)簽
3.2.1 defineObjects標(biāo)簽
3.2.2 renderURL標(biāo)簽
3.2.3 actionURL標(biāo)簽
3.2.4 param標(biāo)簽
3.2.5 namespace標(biāo)簽
第三節(jié) Portal的對(duì)象
3.3.1 Request對(duì)象
3.3.2 Response對(duì)象
3.3.3 PortletConfig對(duì)象
3.3.4 Session對(duì)象
3.3.5 Preference對(duì)象
第四節(jié) 編寫自己的Portlet類
3.4.1 開(kāi)發(fā)環(huán)境
3.4.2 準(zhǔn)備工作
3.4.3 HelloWorldPortlet
3.4.4 HelloJSPPortlet
第五節(jié) 修改Web部署描述文件
第六節(jié) 創(chuàng)建Liferay Portal部署描述文件
第三部分 Liferay Portal部署
第四章 部署自己的Portlet
第一節(jié) 手動(dòng)部署
第二節(jié) Ant自動(dòng)部署
第三節(jié) 加入Liferay Portal自有列表
第四節(jié) 普通Java Web應(yīng)用轉(zhuǎn)化為Portlet應(yīng)用
第四部分 附錄
第五章 相關(guān)資源
第一節(jié) 資源網(wǎng)站
第二節(jié) 示例
第六章 參考資料
后序
第一部分 Liferay Portal 架構(gòu)解析
本部分主要內(nèi)容
Portal 服務(wù)器 Portal 容器 Portlet
第一章 Liferay Portal
作為一個(gè)開(kāi)源Portal產(chǎn)品,Liferay Portal提供對(duì)多個(gè)獨(dú)立系統(tǒng)的內(nèi)容集成,幫助多個(gè)組織實(shí)現(xiàn)更有效的合作。與其他商業(yè)的Portal產(chǎn)品相比,Liferay Portal有著一系列的優(yōu)良特性,而且不需要付費(fèi)。
第一節(jié) Portal規(guī)范
隨著Portal的興起,越來(lái)越多的公司開(kāi)始涉足Portal產(chǎn)品開(kāi)發(fā),并組建各自的Portal組件和基于其的產(chǎn)品,比如IBM、BEA、MicroSoft、SAP、Apache等。各個(gè)廠商的接口互不兼容,給軟件開(kāi)發(fā)商以及開(kāi)發(fā)人員帶來(lái)諸多不便。
1.1.1 JSR168
為
此,JCP組織發(fā)布了JSR168(Java Specification Request),Portlet Specification
V1.0,用來(lái)提供不同的Portal和Portlet之間的互通性。只要開(kāi)發(fā)的Portlet遵循JSR168,則就可以在所有遵循JSR168的
Portal上部署運(yùn)行。
JSR168中定義了Portal的實(shí)現(xiàn)規(guī)范和接口,并對(duì)理想的Portlet進(jìn)行了詳細(xì)的規(guī)劃和描述。
1.1.2 WSRP
WSRP
是OASIS Web Service for Remote Portlet的縮寫。WSRP是Web
Service的一種新的商業(yè)應(yīng)用,一種新的標(biāo)準(zhǔn),主要用來(lái)簡(jiǎn)化Portal對(duì)于各種資源或者程序整合的復(fù)雜度,可以避免編程帶來(lái)的整合麻煩和問(wèn)題。而且
Portal管理員可以從海量的WSRP服務(wù)中選擇需要的功能用以整合到目前所用的Portal中。它有三種角色:
①、生產(chǎn)者 提供Portlet
②、消費(fèi)者 使用Portlet
③、終端用戶 最終用戶
它的特點(diǎn)在于生產(chǎn)者將消費(fèi)者所需要的信息通過(guò)WSRP返回給消費(fèi)者,這些信息是相對(duì)標(biāo)記片斷,例如HTML、XHTML等,可以直接嵌入用戶的頁(yè)面中,而不用像Web Service一樣開(kāi)發(fā)用戶端接口。
實(shí)現(xiàn)這個(gè)規(guī)范,Portal可以跟各式各樣的數(shù)據(jù)源打交道,徹底終結(jié)信息孤島的窘境。
第二節(jié) 什么是Portal
Portal是基于Web的,以“應(yīng)用整合”和“消除信息孤島”為最終目的,提供單點(diǎn)登錄、內(nèi)容聚合、個(gè)性化門戶定制等功能的綜合信息系統(tǒng)。
完整的Portal通常由Portal服務(wù)器、Portlet容器、Portlet構(gòu)成。
1.2.1 Portal 服務(wù)器
Portal
服務(wù)器是容納Portlet容器,支持Portlet呈現(xiàn)的普通或者特殊Web服務(wù)器。Portal服務(wù)器通常會(huì)提供個(gè)性化設(shè)置、單點(diǎn)登錄、內(nèi)容聚合、信
息發(fā)布、權(quán)限管理等功能,支持各種信息數(shù)據(jù)來(lái)源,并將這些數(shù)據(jù)信息放在網(wǎng)頁(yè)中組合而成,提供個(gè)性化的內(nèi)容定制,不同權(quán)限的瀏覽者能夠?yàn)g覽不同的信息內(nèi)容。
通常,Portal提供以下功能:
單點(diǎn)登錄:Portal通常采用ACL、SSL、LDAP等業(yè)界標(biāo)準(zhǔn)的安全技術(shù),提供對(duì)所有現(xiàn)有應(yīng)用系統(tǒng)的安全
集成,只需在Portal的唯一入口上登錄一次,就可以訪問(wèn)所有應(yīng)用系統(tǒng)和數(shù)據(jù)。對(duì)于安全性要求較高的應(yīng)用系統(tǒng),如電子商務(wù)平臺(tái)、交易系統(tǒng)等,通過(guò)擴(kuò)展接
口傳遞用戶身份信息,如數(shù)字證書信息、數(shù)字簽名信息等,進(jìn)行二次身份認(rèn)證,保證單點(diǎn)登陸的安全性。
權(quán)限控制:系統(tǒng)采用LDAP對(duì)用戶資源進(jìn)行統(tǒng)一的管理,同時(shí)提供二次開(kāi)發(fā)接口,可以與其他應(yīng)用系統(tǒng)的用戶管理模塊對(duì)接,并能隨相關(guān)業(yè)務(wù)系統(tǒng)實(shí)時(shí)更新訪問(wèn)權(quán)限。通過(guò)完善的授權(quán)機(jī)制及存取控制,用戶訪問(wèn)權(quán)限控制到字段級(jí)別,確保用戶只能訪問(wèn)具有權(quán)限的應(yīng)用系統(tǒng)及相關(guān)信息。
內(nèi)容管理: 實(shí)現(xiàn)應(yīng)用系統(tǒng)之間實(shí)時(shí)交換信息。采用多種緩存機(jī)制,保證內(nèi)容交換的性能和準(zhǔn)確性。采用基于XML的Rich Site Summary (RSS)標(biāo)準(zhǔn),迅速在各應(yīng)用系統(tǒng)之間傳播最新變化。
信息發(fā)布: 實(shí)現(xiàn)信息門戶內(nèi)容的動(dòng)態(tài)維護(hù)。動(dòng)態(tài)網(wǎng)站系統(tǒng)可與OA協(xié)同辦公系統(tǒng)、知識(shí)管理系統(tǒng)等集成,網(wǎng)站信息須經(jīng)OA系統(tǒng)的審批流程流轉(zhuǎn)通過(guò)后或知識(shí)管理平臺(tái)設(shè)置具有外部共享權(quán)限后才可正式發(fā)布,真正實(shí)現(xiàn)內(nèi)外信息發(fā)布的同步。
文
件管理:
系統(tǒng)實(shí)現(xiàn)無(wú)縫集成多種數(shù)據(jù)源,包括:數(shù)據(jù)庫(kù)、文檔(Office文檔、PDF、AutoCAD、甚至ZIP文檔)、Web網(wǎng)頁(yè)、FTP站點(diǎn)等,并對(duì)數(shù)據(jù)按
業(yè)務(wù)要求和職務(wù)特點(diǎn)加以分析整理,通過(guò)統(tǒng)一Web界面主動(dòng)推送(Push)至用戶的門戶桌面,幫助用戶做出及時(shí)、正確的決策。
1.2.2 Portlet容器
Portlet容器提供Portlet執(zhí)行的環(huán)境,包含很多Portlet并管理它們的生命周期,保存Portlet的定制信息。
一
個(gè)Portal容器接收到來(lái)自Portal的請(qǐng)求后,接著將這個(gè)請(qǐng)求傳遞給存在Portal容器的Portlet
執(zhí)行。Portlet容器沒(méi)有義務(wù)去組合Portlet 產(chǎn)生的信息內(nèi)容,這個(gè)工作必須由Portal來(lái)處理。Portal和
Portal容器可以放在一起視為同一個(gè)系統(tǒng)的組件,或者分開(kāi)成為兩個(gè)獨(dú)立的組件。
Portlet容器是普通Web
Servlet容器的擴(kuò)展,所以一個(gè)Portlet容器可以構(gòu)建于一個(gè)已經(jīng)存在的Servlet容器或者可能實(shí)現(xiàn)全部Web
Servlet容器的全部功能。無(wú)論P(yáng)ortlet容器怎么實(shí)現(xiàn),它的運(yùn)行環(huán)境總是假定它支持Servlet2.3規(guī)范。
通常,Portlet容器擴(kuò)展自普通的Servlet容器。
第三節(jié) 什么是Portlet
Portlet是Portal中最重要的
組件,負(fù)責(zé)在Portal中呈現(xiàn)信息內(nèi)容,有相應(yīng)的生命周期。通過(guò)自定義Portlet,用戶很容易定義個(gè)性化的Portal頁(yè)面。Portlet由
Portlet容器負(fù)責(zé)管理、處理請(qǐng)求并返回動(dòng)態(tài)頁(yè)面,可以作為Portal的可即插即用的界面組件。
1.3.1 Portlet
一個(gè)Portlet是以Java技術(shù)為技術(shù)的Web組件,由Portlet容器所管理,專門處理客戶的 信息請(qǐng)求以及產(chǎn)生各種動(dòng)態(tài)的信息內(nèi)容。Portlet 為可插式的客戶界面組件,提供呈現(xiàn)層成為一個(gè)信息系統(tǒng)。
這
些由Portlet產(chǎn)生的內(nèi)容也被稱為片段,而片段是具有一些規(guī)則的標(biāo)記( HTML、XHTML、WML
),而且可以和其他的片段組合而成一個(gè)復(fù)雜的文件。一個(gè)或多個(gè) Portlet 的內(nèi)容聚合而成為一個(gè) Portal 網(wǎng)頁(yè)。而 Portlet
的生命周期是被 Portlet 容器所管理控制的。
客戶端和Portlet的互動(dòng)是由Portal通過(guò)典型的請(qǐng)求/響應(yīng)方式實(shí)現(xiàn),正常來(lái)說(shuō),客
戶會(huì)和Portlet所產(chǎn)生的內(nèi)容互動(dòng),舉例來(lái)說(shuō),根據(jù)下一步的連接或者是確認(rèn)送出的表單,結(jié)果
Portal將會(huì)接收到Portlet的動(dòng)作,將這個(gè)處理狀況轉(zhuǎn)向到目標(biāo)Portlet。這些Portlet
內(nèi)容的產(chǎn)生可能會(huì)因?yàn)椴煌氖褂谜叨胁煌淖兓耆歉鶕?jù)客戶對(duì)于這個(gè)Portlet的設(shè)置。
1.3.2 Portlet與Servlet的關(guān)系
Portlet
被定義成為一個(gè)新的組件,具有新的明確的界面與行為。為了盡可能與現(xiàn)有的 Servlet 結(jié)合達(dá)到重復(fù)使用的目的,Portlet 的規(guī)范利用了
Servlet 的規(guī)范,許多觀念都很相似的,結(jié)合 Portlet、Servlet 及 Jsp 在同一個(gè)網(wǎng)站系統(tǒng)中,我們稱為Portlet 應(yīng)用
。在同一個(gè) Portlet 應(yīng)用 中,他們將分享同一個(gè)類加載器(ClassLoader),上下文(Context) 及 Session。
①、Portlet 和 Servlet 的相似之處
@ Portlet 也是 Java 技術(shù)的 web 組件
@ Portlet 也是有特定的 container 在管理
@ Portlet 可以動(dòng)態(tài)產(chǎn)生各種內(nèi)容
@ Portlet 的生命周期由 container 所管理
@ Portlet 和客戶端的互動(dòng)是通過(guò) request/response 的機(jī)制
②、Portlet 和 Servlet 也有一些不同
@ Portlet 只產(chǎn)生 markup 信息片段,不是完整的網(wǎng)頁(yè)文件。而 Portal 會(huì)將所有的 Portlet markup 信息片段放到一個(gè)完整的 Portal 網(wǎng)頁(yè)。
@ Portlet 不會(huì)和 URL 有直接的關(guān)系
@ 客戶端必須通過(guò) portal 系統(tǒng)才能和 Portlet 互動(dòng)
@ Portlet 有一些定義好的 request 處理,action request 以及 render request。
@ Portlet 默認(rèn)定義 Portlet modes 及窗口狀態(tài)可以指出在網(wǎng)頁(yè)中該 Portlet 的哪個(gè)功能正在執(zhí)行及現(xiàn)在的 狀態(tài)。
@ Portlet 可以在同一個(gè) portal 網(wǎng)頁(yè)之中存在多個(gè)。
③、Portlet 有一些附加的功能是 Servlet 所沒(méi)有的
@ Portlet 能夠存取及儲(chǔ)存永久配置文件及定制資料。
@ Portlet 可以存取使用者數(shù)據(jù)
@ Portlet 具有 URL 的重寫功能在文件中去動(dòng)態(tài)建立連結(jié),允許 portal server 不用去知道如何在網(wǎng)頁(yè)的片 段之中建立連結(jié)及動(dòng)作。
@ Portlet 可以儲(chǔ)存臨時(shí)性的數(shù)據(jù)在 Portlet session 之中,擁有兩個(gè)不同的范圍 :
application-wide scope 及 Portlet private scope 。
④、Portlet 不具有一些功能, 但是 Servlet 卻有提供
@ Servlet 具有設(shè)置輸出的文字編碼( character set encoding)方式
@ Servlet可以設(shè)置 HTTP 輸出的 header
@ Servlet才能夠接收客戶對(duì)于 portal 發(fā)出的 URL 請(qǐng)求
1.3.3 Portlet的生命周期
一個(gè)Portlet有著良好的生命周期管理,定義了怎樣裝載,實(shí)例化和初始化,怎樣響應(yīng)來(lái)自客戶端的請(qǐng)求及怎樣送出服務(wù)。這個(gè)Portlet生命周期由Portlet接口的init,processAction,render和destroy方法來(lái)表達(dá)。
載入和實(shí)例化:Portlet容器負(fù)責(zé)載入和實(shí)例化Portlet。當(dāng)Portlet容器運(yùn)行Portlet應(yīng)用或者延遲到Portlet需要服務(wù)使用者的請(qǐng)求時(shí),Portlet就會(huì)被載入并實(shí)例化。載入Portlet類后,Portlet類隨即被實(shí)例化。
初
始化:Portlet類實(shí)例化后,Portlet容器還需要初始化Portlet。以調(diào)用Portlet去響應(yīng)客戶端的請(qǐng)求。Portlet容器呼叫
Portlet接口中的init方法初始化Portlet。擴(kuò)展自PortletConfig的類可以取出定義在部署描述文件中的初始化參數(shù),以及
Resource Bundle。
初始化異常:在 Portlet初始化期間,Portlet可能會(huì)丟出
UnavailableException 或 PortletException 異常。此時(shí),Portlet容器不能把
Portlet置入已啟動(dòng)的服務(wù),并且 Portlet容器必需釋放這個(gè) Portlet。
destory方法不能被呼叫,因?yàn)槌跏蓟徽J(rèn)為執(zhí)行失敗。發(fā)生 失敗后,Portlet容器會(huì)嘗試著重新實(shí)例化及初始化
Portlet。這個(gè)異常處理的規(guī)則是:由一個(gè)UnavailableException
指定一個(gè)不能執(zhí)行的最小時(shí)間,當(dāng)此異常發(fā)生時(shí),Portlet容器必需等到指定時(shí)間過(guò)去后才產(chǎn)生并且初始化一個(gè)新的 Portlet。
在初始化過(guò)程中所丟出的 Runtime Exception異常,被當(dāng)作 PortletException 來(lái)處理。
第四節(jié) Liferay Portal工作原理
Portal系統(tǒng)根據(jù)需要由一個(gè)或者多個(gè)Portal頁(yè)面組成,每個(gè)Portal頁(yè)面包含零個(gè)或者多個(gè)的Portlet。每個(gè)Portlet呈現(xiàn)自己的信息內(nèi)容,以此實(shí)現(xiàn)內(nèi)容聚合。通過(guò)定義每個(gè)Portlet的可用權(quán)限,實(shí)現(xiàn)個(gè)性化的桌面信息定制。
1.4.1 Portlet 樣式以及窗口狀態(tài)
圖1.4.1-1
圖1.4.1-2
JCP
組織提出的JSR168規(guī)范定義了Portlet的實(shí)現(xiàn)標(biāo)準(zhǔn)。每個(gè)Portlet對(duì)外表現(xiàn)為一個(gè)小窗口,有自己的默認(rèn)樣式和窗口狀態(tài)。如上圖,
Portlet有自己的標(biāo)題,瀏覽狀態(tài)下支持編輯、關(guān)閉、上移、下移、最大化、最小化功能,編輯狀態(tài)下支持返回和關(guān)閉功能。從各種數(shù)據(jù)來(lái)源提取的信息以
Portlet內(nèi)容的形式呈現(xiàn)在Portal中。
Portlet樣式指出 Portlet正處于什么模式,Portlet通常會(huì)根據(jù)所處的模式而執(zhí)行不同的工作并產(chǎn)生不同的內(nèi)容。
Portlet模式讓 Portlet決定它該顯示什么內(nèi)容和執(zhí)行什么動(dòng)作。調(diào)用一個(gè) Portlet的時(shí)候,Portlet 容器會(huì)提供一個(gè) Portlet模式給那個(gè) Portlet。當(dāng)在處理一個(gè)請(qǐng)求動(dòng)作時(shí),Portlet 的模式是可以用程序來(lái)改變的。
JSR168規(guī)范定義了三個(gè)Portlet模式: 瀏覽、編輯和幫助,Liferay Portal支持其中的全部三個(gè)模式。同時(shí)Portal是可以根據(jù)使用者的角色,來(lái)決定是要提供(顯示)哪幾個(gè) Portlet 模式給使用者操作。
例如,匿名使用者可以操作瀏覽和幫助等 Portlet 模式的內(nèi)容, 而只有授權(quán)過(guò)的使用者可以操作編輯這個(gè) Portlet 模式所提供的內(nèi)容或動(dòng)作。
在瀏覽這個(gè)Portlet模式里,所被期望要提供的功能是產(chǎn)生標(biāo)記語(yǔ)言來(lái)表現(xiàn)此時(shí) Portlet的狀態(tài)。 舉例來(lái)說(shuō), Portlet的 瀏覽 模式可以包含一個(gè)或多個(gè)畫面讓使用者可以瀏覽與互動(dòng), 或是一些不需要與使用者互動(dòng)的靜態(tài)內(nèi)容。
在編輯這個(gè)Portlet模式里, Portlet 需要提供內(nèi)容和邏輯來(lái)讓使用者定制 Portlet 的行為。典型的說(shuō), 編輯模式的 Portlet 會(huì)設(shè)定或更新 Portlet 的參數(shù)設(shè)定值。
在幫助這個(gè)模式里,Portlet應(yīng)該提供有關(guān)這個(gè) Portlet的幫助信息。這個(gè)幫助信息可以是有關(guān)這個(gè) Portlet的簡(jiǎn)單且條理清楚的視窗說(shuō)明或是詳細(xì)的說(shuō)明整個(gè)來(lái)龍去脈。所有的Portlet并不需要都提供幫助這個(gè)模式。
一
個(gè) Portlet可以根據(jù)窗口狀態(tài)來(lái)決定在一個(gè)頁(yè)面里該占多少空間。 當(dāng)調(diào)用一個(gè) Portlet時(shí), Portlet容器 需要告訴該
Portlet目前的窗口狀態(tài)。 此時(shí) Portlet可以根據(jù)窗口狀態(tài)來(lái)決定它該對(duì)多少信息作處理。 在處理請(qǐng)求的過(guò)程中,
Portlet可以通過(guò)程序的方式來(lái)改變窗口狀態(tài)。
1.4.2 Portal頁(yè)面
圖1.4.2-1
每個(gè)Portal
頁(yè)面包含零個(gè)或者多個(gè)Portlet小窗口,構(gòu)成一個(gè)完整的信息呈現(xiàn)頁(yè)面。Portal在啟動(dòng)之后根據(jù)Portlet配置文件等信息,給Portlet的
標(biāo)題等屬性賦值,賦予Portlet編輯、關(guān)閉等各種控制按鈕,使Portlet成為一個(gè)標(biāo)準(zhǔn)的Portlet窗口。Portlet合并這些
Portlet窗口,組成一個(gè)完整的文檔,即Portal頁(yè)面。每個(gè)Portlet都處于相應(yīng)的布局當(dāng)中,呈現(xiàn)事先定義的內(nèi)容,表現(xiàn)Portal公共的品
質(zhì)。而且Portlet可以在不同的布局之間切換。Portlet響應(yīng)客戶端的請(qǐng)求,并將請(qǐng)求提交到相應(yīng)的URL進(jìn)行邏輯處理。
Portlet開(kāi)發(fā)完畢之后,部署到Portal服務(wù)器,由Portal服務(wù)器負(fù)責(zé)組織、權(quán)限控制和呈現(xiàn)。Portal頁(yè)面創(chuàng)建過(guò)程如下:
Portlet 在 Portlet容器內(nèi)執(zhí)行,Portlet容器接收 Portlet產(chǎn)生的內(nèi)容。通常 Portlet容器將這些內(nèi)容提交給 Portlet服務(wù)器,Portlet服務(wù)器依照這些內(nèi)容建立Portal頁(yè)面,然后將它傳給客戶端呈現(xiàn)。具體流程如下圖:
Portlet 在 Portlet容器內(nèi)執(zhí)行,Portlet容器接收 Portlet產(chǎn)生的內(nèi)容。通常 Portlet容器將這些內(nèi)容提交給 Portlet服務(wù)器,Portlet服務(wù)器依照這些內(nèi)容建立Portal頁(yè)面,然后將它傳給客戶端呈現(xiàn)。具體流程如下圖:
Portal頁(yè)面的請(qǐng)求過(guò)程如下:
使
用者經(jīng)由客戶端設(shè)備(例如瀏覽器)存取 Portal,Portal 根據(jù)接收到的請(qǐng)求決定哪些 Portlet 需要被執(zhí)行以滿足需求。Portal
通過(guò)Portlet容器呼叫 Portlet,然后由 Portlet產(chǎn)生的片段建立Portal頁(yè)面,再傳回客戶端呈現(xiàn)給使用者。具體流程如下圖:
|
第二章Liferay Portal的使用
Liferay Portal分為Professional 和 Enterprise兩個(gè)版本。
Liferay
Portal支持多個(gè)應(yīng)用服務(wù)器和Servlet容器。Liferay Portal
Ent版本需要一個(gè)健壯的J2EE服務(wù)器,而Pro版本只要一個(gè)普通的Servlet服務(wù)器就可以運(yùn)行。如果需要運(yùn)行EJB,建議使用Pro版本。兩個(gè)版
本的源碼和應(yīng)用接口都是一樣的。
默認(rèn)的,Pro版本分別集成Tomcat / Jetty / Resin作為Web服務(wù)器,采用Struts作為Web框架,實(shí)現(xiàn)輕量級(jí)的系統(tǒng)架構(gòu)。Enterprise集成JBoss作為Web服務(wù)器,采用Spring作為Web框架,兼顧EJB。
Liferay Portal默認(rèn)集成HSQL數(shù)據(jù)庫(kù),來(lái)持久化保存用戶自定義的數(shù)據(jù)。通過(guò)修改集成在Liferay Portal的Tomcat的部署描述文件,用戶可以更改數(shù)據(jù)源。Liferay Portal官方網(wǎng)站提供了數(shù)據(jù)庫(kù)表的生成腳本。
下面以Pro版本(Tomcat服務(wù)器)為例,講述Liferay Portal的用戶策略、內(nèi)容布局、桌面和品質(zhì)。
第一節(jié) Liferay Portal安裝
由于Liferay Portal Pro版本集成了Tomcat服務(wù)器V5,所以只要把應(yīng)用包下載解壓就可以直接運(yùn)行。
1、
從 http://www.iferay.om/web/guest/downloads/portal_pro 下載Pro版本zip包,
解壓到目錄{PORTAL_HOME}, 目錄結(jié)構(gòu)相對(duì)普通的Tomcat增加了Liferay文件夾。Liferay是默認(rèn)的Web應(yīng)用。
2、正確安裝JDK1.4或者JDK1.5,并在環(huán)境變量里面正確配置JAVA_HOME變量。
圖2.1-1
3、從命令行啟動(dòng){PORTAL_HOME}/bin/startup.bat,啟動(dòng)Liferay Portal。
4、在瀏覽器地址欄輸入http://localhost ,訪問(wèn)Portal首頁(yè)。
5、用Login為test@liferay.com密碼為test的用戶登錄Portal系統(tǒng),得到的是一個(gè)Demo的首頁(yè)。如果啟動(dòng)呈現(xiàn)異常,請(qǐng)查看Tomcat控制臺(tái)查找原因。
Liferay Portal啟動(dòng)之后,HSQL數(shù)據(jù)庫(kù)自動(dòng)啟動(dòng)。
登錄系統(tǒng)后,點(diǎn)擊右上角“My Account”鏈接,在“Display”選項(xiàng)卡中將Language改為“Chinese(China)”,以便中文化Portal界面。
第二節(jié) Liferay Portal的用戶策略
Liferay Portal通過(guò)定義嚴(yán)謹(jǐn)?shù)挠脩舨呗浴㈧`活的可個(gè)性化定制的內(nèi)容和布局以及豐富可定制的品質(zhì)策略,實(shí)現(xiàn)靈活的可定制的產(chǎn)品理念。
Liferay
Portal采用用戶-用戶組-角色-Portlet的關(guān)聯(lián)方式來(lái)實(shí)現(xiàn)用戶權(quán)限的管理。用戶錄屬于用戶組(也可以單獨(dú)存在),該用戶組具有某種(多種)角
色,角色分配給用戶組,也可以直接分配給用戶。而操作某個(gè)Portlet 需要具有其指定的角色。下面通過(guò)實(shí)例操作,來(lái)了解和體驗(yàn)一下Liferay
Portal的用戶管理策略。
2.2.1 定義用戶
Liferay
Portal的用戶管理在系統(tǒng)管理的Portlet中。缺省只有系統(tǒng)管理員才能使用。登錄Portal后,可以在默認(rèn)的桌面上找到“系統(tǒng)管理”
Portlet。如果沒(méi)有,從頁(yè)面底部的選擇框中選擇“系統(tǒng)管理”添加上。也可以通過(guò)右上角“CMS”桌面的“內(nèi)容和布局”頁(yè)面找到管理入口。
從“系統(tǒng)管理”Portlet中選擇“用戶”項(xiàng),進(jìn)入用戶管理界面。2.2.2 添加用戶
圖2.2.1-2所示頁(yè)面右邊為“新增用戶”列,
填入你所要增加的用戶名稱,姓氏,用戶標(biāo)識(shí)(可自動(dòng)生成),郵件地址,密碼(可自動(dòng)生成)等。可以修改該用戶所具有的用戶組和角色信息(也可創(chuàng)建之后再修
改)。用戶標(biāo)識(shí)必須是系統(tǒng)唯一的,所以請(qǐng)確保你所輸入的用戶標(biāo)識(shí)與已有的不沖突。
點(diǎn)擊“新增用戶”,我們成功增加一位用戶標(biāo)示為“educhina”的用戶,如圖2.2.1-2所示。左側(cè)列表中新增一項(xiàng)“educhina eamoi”。然后我們就可修改這位用戶的用戶組,角色,個(gè)人檔案等信息了。
2.2.3 修改用戶
選擇用戶列表中一項(xiàng),然后點(diǎn)擊底部的三個(gè)編輯按鈕,就可以分別編輯該用戶的用戶組、角色、檔案等信息了。
此處我們選擇用戶“educhina eamoi”,然后選擇“編輯檔案”,出現(xiàn)檔案編輯頁(yè)面。如圖2.2.3-3所示。填寫你想要修改的信息,點(diǎn)擊對(duì)應(yīng)的“更新”按鈕即可完成修改。需要注意的是整個(gè)檔案頁(yè)面分成幾個(gè)部分,需要分別修改更新。
選
擇用戶“educhina
eamoi”,然后選擇“編輯角色”,進(jìn)入角色編輯頁(yè)面,如圖2.2.3-4所示。左側(cè)列表框?yàn)楫?dāng)前該用戶所具有的角色,右側(cè)列表為所有可用的角色。要賦
給用戶新角色,則從右側(cè)選擇一項(xiàng)或多項(xiàng),通過(guò)中間的轉(zhuǎn)移按鈕,從右側(cè)添加至左側(cè)。要?jiǎng)h減用戶角色,則從左側(cè)移至右側(cè)。最后點(diǎn)擊底部的“更新”即可。更新完
頁(yè)面會(huì)自動(dòng)返回。
編輯用戶組的操作同上。2.2.4 定義用戶組
用戶組是對(duì)具有相同角色的用戶的聚合。只要把用戶需要的角色賦給用戶組,則該用戶組內(nèi)所有的用戶就都具備了該角色,具有該角色所有的權(quán)限,這樣子就簡(jiǎn)化了用戶權(quán)限管理。
用戶組還有一個(gè)共用首頁(yè)面的概念,是該用戶組所有用戶共享的頁(yè)面。這些用戶可以看到一個(gè)內(nèi)容布局一致的頁(yè)面,用以在用戶組中共享信息。
從系統(tǒng)管理中選擇[用戶組]項(xiàng),進(jìn)入用戶組定義頁(yè)面。如圖2.2.4-1所示:
圖2.2.4-1
2.2.5 新增、重命名用戶組
圖中左側(cè)為用戶組列表,右側(cè)為新增,和重命名。
在新增部分直接添入用戶組名稱,點(diǎn)擊“新增用戶組”即可。
選擇列表中一個(gè)用戶組,然后在右側(cè)下方添入要修改的新組名,點(diǎn)擊“更新”既可。
“友好的URL”為該用戶組的共用首頁(yè)面設(shè)置URL。
2.2.6 修改用戶組
對(duì)于用戶組我們可以修改它的角色,所包含的用戶和該用戶組的共用首頁(yè)面。
選擇用戶組列表中一項(xiàng),然后點(diǎn)擊底部的“編輯角色”,進(jìn)入用戶組角色編輯頁(yè)面,如圖2.2.6-1所示。頁(yè)面左側(cè)為用戶組當(dāng)前已具備的角色,右側(cè)為所有可用角色。添加刪除操作同[2.2.3修改用戶]。更新完會(huì)自動(dòng)返回用戶組列表頁(yè)面。
圖2.2.6-1
選擇用戶組列表中一項(xiàng),然后點(diǎn)擊底部的“編輯用戶”,進(jìn)入用戶組用戶編輯頁(yè)面,如圖2.2.6-2所示。頁(yè)面左側(cè)為用戶組 當(dāng)前包含的用戶,右側(cè)為所有用戶。添加刪除操作同[2.2.3修改用戶]。更新完會(huì)自動(dòng)返回用戶組列表頁(yè)面。
圖2.2.6-2
選擇用戶組列表中一項(xiàng),然后點(diǎn)擊底部的“編輯頁(yè)面”,進(jìn)入用戶組首頁(yè)編輯頁(yè)面,如圖2.2.6-3所示。
首先增加一個(gè)新頁(yè)。在“處理子頁(yè)”一欄,填入新頁(yè)的名字,選擇類型,點(diǎn)擊“新增頁(yè)面”,左側(cè)樹(shù)狀列表中會(huì)增添一個(gè)以新頁(yè)名字為標(biāo)題的新項(xiàng)。
然后為新頁(yè)設(shè)置布局。點(diǎn)擊左側(cè)列表中的新頁(yè),右側(cè)出現(xiàn)布局編輯頁(yè)面,如圖2.2.6-4所示。詳細(xì)設(shè)置布局的操作可參考所述。
圖2.2.6-4
2.2.7 定義角色
角色是對(duì)用戶身份的一種定義。不同的角色具有不同的權(quán)限。被賦予這種角色的用戶自然就獲得了該角色的權(quán)限。
從系統(tǒng)管理中選擇[角色]項(xiàng),進(jìn)入角色定義頁(yè)面。如圖2.2.7-1所示。
圖2.2.7-1
2.2.8 新增、重命名角色
圖中左側(cè)為角色列表,右側(cè)為新增,和重命名。
在新增部分輸入角色名稱,點(diǎn)擊“新增角色”即可新增一個(gè)角色。
選擇列表中一個(gè)角色,然后在右側(cè)下方對(duì)應(yīng)欄位填入新角色名,點(diǎn)擊“重命名角色”即可重命名該角色。
2.2.9 修改用戶組角色
對(duì)于角色,我們可以修改它的用戶組和用戶。該操作可以通過(guò)修改用戶組和用戶的角色來(lái)完成。
選擇角色列表中一項(xiàng),然后點(diǎn)擊底部的“編輯用戶組”,進(jìn)入角色的用戶組編輯頁(yè)面,如圖2.2.9-1所示。頁(yè)面左側(cè)為已具備當(dāng)前角色的用戶組,右側(cè)為所有用戶組。添加刪除操作同[2.2.3修改用戶]。更新后自動(dòng)返回角色列表頁(yè)面。
|
選擇角色列表中一項(xiàng),然后點(diǎn)擊底部的“編輯用戶”,進(jìn)入角色的用戶編輯頁(yè)面,如圖2.2.9-2所示。頁(yè)面左側(cè)為已具備當(dāng)前角色的用戶,右側(cè)為所有用戶。添加刪除操作同[2.2.3修改用戶]。更新后自動(dòng)返回角色列表頁(yè)面。
圖2.2.9-2
2.2.10 定義Portlet的角色
通過(guò)為Portlet設(shè)置必需的角色,我們實(shí)現(xiàn)了用戶與Portlet的關(guān)聯(lián)。只有當(dāng)用戶或所屬的用戶組具有Portlet所必需的角色,他才能操作該P(yáng)ortlet。
從系統(tǒng)管理中選擇[Portlet]項(xiàng),進(jìn)入Portlet定制頁(yè)面。如圖2.2.10-1所示。頁(yè)面中顯示了目前系統(tǒng)中可用的Portlet列表,列表中顯示了Portlet目前的狀態(tài)和必需的角色。
圖2.2.10-1
選擇一個(gè)Portlet,點(diǎn)擊“編輯”進(jìn)入Portlet定制頁(yè)面,如圖2.2.10-2所示。頁(yè)面左側(cè)為Portlet必需的角色,右側(cè)為所有角色。添加刪除操作同[2.2.3修改用戶]。
圖2.2.10 - 2
第三節(jié) Liferay Portal內(nèi)容和布局
Portlet
容器采用布局來(lái)對(duì)包含的Portlet進(jìn)行管理并呈現(xiàn),不同的布局決定了不同的Portlet呈現(xiàn)效果。每個(gè)加入到Portal服務(wù)器的Portlet必
須屬于某個(gè)布局,才能夠被使用者所看到。內(nèi)容則是Portlet對(duì)外呈現(xiàn)的信息片斷,是Portlet的核心。兩者都是Portal的重要組成部分。
Liferay Portal采用開(kāi)源框架Struts的Tiles來(lái)管理內(nèi)容和布局。
2.3.1 什么是布局
布局,即Layout,也可以稱為布局管理器,是Portlet容器管理Portlet的一個(gè)重要工具。一個(gè)布局,在生成的Portal頁(yè)面中,呈現(xiàn)出單行多列或者多行多列的效果。而Portlet就內(nèi)嵌在某一列中。
在Liferay Portal中,將列分為寬欄和窄欄。通常,寬欄占據(jù)頁(yè)面2/3的寬度,窄欄占據(jù)頁(yè)面1/3的寬度。每個(gè)Portlet在部署的時(shí)候都必須在部署描述符文件中指定Portlet是被部署在寬欄或者窄欄當(dāng)中,默認(rèn)是部署在寬欄中。
圖 2.3.1-1
Liferay
Portal采用tpl文件來(lái)定義布局,這些tpl文件存儲(chǔ)在{PORTAL_HOME}
/liferay/html/layouttpl文件夾中。在tpl文件中,規(guī)定每個(gè)列的寬度。當(dāng)Portlet加入到列中時(shí),取得當(dāng)前列的寬度,然后根
據(jù)這個(gè)寬度確定Portlet窗口的顯示寬度。tpl文件采用標(biāo)準(zhǔn)的HTML代碼和Liferay Portal自定義的標(biāo)簽來(lái)定義布局。如下圖:
圖2.3.1-2
只要把定義的tpl文件路徑加入到部署描述文件中,Liferay Portal在啟動(dòng)的時(shí)候就可以自動(dòng)載入,供系統(tǒng)調(diào)用。如下圖:
Liferay Portal默認(rèn)的布局允許有一列、二列、三列的布局。二次開(kāi)發(fā)的時(shí)候可以定義自己的布局文件。
在每個(gè)列的底部,有一個(gè)下拉列表框,列出本列可用的所有Portlet。列表框旁邊的“添加”按鈕,則可以將選中的按鈕添加到列中顯示。
圖2.3.1-4
圖2.3.1-5
圖2.3.1-6
2.3.2 什么是內(nèi)容
內(nèi)容具體指Portlet顯示出來(lái)的標(biāo)記片斷,稱為Portlet內(nèi)容。通常,當(dāng)Portlet窗口處于瀏覽或者編輯狀態(tài)的時(shí)候,就會(huì)表現(xiàn)相應(yīng)的Portlet內(nèi)容。內(nèi)容在開(kāi)發(fā)Portlet的時(shí)候確定。
Portlet對(duì)各種來(lái)源的數(shù)據(jù)進(jìn)行加工和邏輯處理,最后輸出為一些規(guī)則的標(biāo)記(HTML、XHTML、WML),最后在Portlet容器中形成Portlet窗口,供Portal組合成為Portal頁(yè)面。
內(nèi)容是Portlet的信息主體,它形成的表單、鏈接等同時(shí)接受使用者的信息請(qǐng)求或者數(shù)據(jù)提交,并將系統(tǒng)對(duì)使用者請(qǐng)求的響應(yīng)呈現(xiàn)在客戶端。下圖為以日歷為內(nèi)容的Portlet。
圖2.3.2-1
2.3.3 內(nèi)容布局與Portlet的關(guān)系
通
過(guò)定義布局,對(duì)Portlet進(jìn)行有效管理,是Liferay
Portal容器組織Portlet的有效方式。在相同的列中,Portlet可以很容易的調(diào)整位置。當(dāng)列中的Portlet數(shù)量超過(guò)一個(gè)的時(shí)候,通過(guò)
Portlet右上角的“上移”和“下移”按鈕,可以調(diào)整相鄰Portlet的上下位置。當(dāng)Portlet的內(nèi)容較長(zhǎng)的時(shí)候,可以把Portlet部署到
寬欄中,占據(jù)更大的屏幕空間,以有效的顯示數(shù)據(jù)。相應(yīng)的,如果Portlet內(nèi)容較少時(shí),可以把Portlet部署到窄欄中。
圖2.3.3-1
每個(gè)Portlet在定義的時(shí)候,可以在部署描述文件中定義Portlet所屬的類(Category),每個(gè)類可用的布局,這些定義也可以啟動(dòng)Portal之后在“內(nèi)容與布局”選項(xiàng)卡中修改。
在“修改布局”子選項(xiàng)卡中可以修改的包括桌面的標(biāo)識(shí),如果是單行兩列的布局,還可以調(diào)整寬欄和窄欄的位置。如下圖:利用Liferay Portal提供的工具,可以很方便的修改布局內(nèi)容和它被顯示在Portal頁(yè)面的什么地方。
|
在“處理孩子”子選項(xiàng)卡中,可以定義每個(gè)Portal頁(yè)面的子頁(yè)面,形成頁(yè)面樹(shù)。根節(jié)點(diǎn)的子頁(yè)面會(huì)平行的出現(xiàn)在桌面上。如下圖:
圖2.3.3-4
Portal
是大量信息和系統(tǒng)的集成。Portlet內(nèi)容往往來(lái)源與集成的各個(gè)系統(tǒng)。Portlet面向的用戶通常也是復(fù)雜的。除了在用戶策略中合理定義
Portlet的用戶策略外,也可以對(duì)Portlet內(nèi)容進(jìn)行過(guò)濾,針對(duì)相應(yīng)的用戶顯示適當(dāng)?shù)男畔ⅰ.?dāng)然,這種方法沒(méi)有定義用戶策略那樣來(lái)得直觀。
2.3.4 選擇內(nèi)容和布局
Liferay Portal內(nèi)置了數(shù)個(gè)Portlet應(yīng)用,包括系統(tǒng)管理、日歷、書簽等等。目前,Liferay Portal支持單行單列、單行兩列、單行三列的布局顯示,可以在相應(yīng)桌面的“內(nèi)容和布局”中選擇。
每個(gè)默認(rèn)的Portlet則來(lái)自于各個(gè)數(shù)據(jù)源的既有數(shù)據(jù),或者對(duì)該數(shù)據(jù)的重新加工處理。通過(guò)定義Portlet所屬類別和相應(yīng)的用戶策略,成功實(shí)現(xiàn)Portlet的合理顯示。
Liferay Portal提供了基于Web的工具,可以很方便的在幾種默認(rèn)的布局之間切換。
①、登錄系統(tǒng)后,選擇桌面當(dāng)中的“內(nèi)容和布局”,進(jìn)入布局管理頁(yè)面。
②、選中桌面的第一級(jí)節(jié)點(diǎn),然后在“列數(shù)”中選擇需要的列數(shù)。
③、點(diǎn)擊底部的“更新頁(yè)”按鈕,提交選擇。布局修改生效。返回桌面。
可以看到,單行單列的布局默認(rèn)是一個(gè)寬欄;單行兩列的布局默認(rèn)是一個(gè)寬欄和一個(gè)窄欄;單行三列的布局默認(rèn)是三個(gè)窄欄。
第四節(jié) Liferay Portal的桌面
2.4.1 什么是桌面
定義個(gè)性化的桌面是Portal的標(biāo)準(zhǔn)功能之一。用戶可以把任何允許的Portlet添加到桌面上,構(gòu)建符合自己需求的信息集合。
桌面是用戶定義的Portlet的集合,也是Portlet內(nèi)容的最終呈現(xiàn)媒介之一,可以是一個(gè)Portal頁(yè)面,或者是一個(gè)Portal頁(yè)面集合,里面包含一個(gè)或者多個(gè)的Portlet。每個(gè)桌面通常用一個(gè)或者多個(gè)布局來(lái)管理桌面上的Portlet。
Portlet
在部署之前,會(huì)在部署描述文件中定義該P(yáng)ortlet可用的用戶組和角色。在定義了用戶所屬的用戶組和角色之后,就可以在桌面下方的添加列表中看到該用戶
可用的所有Portlet。用戶可以把任何符合該用戶角色權(quán)限的Portlet添加到相應(yīng)的布局中。這些Portlet和桌面的定制信息會(huì)被Portal
服務(wù)器持久化保存。
圖2.4.1-1
Portal啟動(dòng)之后,根據(jù)定制的Portlet和桌面信息,搜索并實(shí)例化Portlet,構(gòu)建Portal頁(yè)面,把Portlet內(nèi)容顯示在用戶定制的桌面上。
2.4.2 定義個(gè)性化的桌面
在
完成用戶策略、Portlet定義之后,登錄Liferay
Portal,就可以進(jìn)行個(gè)性化桌面的定制了。用戶登錄進(jìn)入到相應(yīng)的桌面后,在相應(yīng)的布局列底部可以看到可用的全部Portlet列表。選中某個(gè)
Portlet,點(diǎn)擊“添加”按鈕,將選中的Portlet添加到列中。對(duì)已經(jīng)添加到列中的全部Portlet,可以通過(guò)點(diǎn)擊Portlet窗口右上角的
“上移”、 “下移”按鈕,調(diào)整Portlet窗口的位置。也可以點(diǎn)擊Portlet窗口右上角的“最大化”
、“最小化”按鈕,改變窗口的狀態(tài)。定制完畢的桌面效果如下圖:第五節(jié) Liferay Portal的品質(zhì)
Liferay Portal支持個(gè)性化的皮膚和外觀設(shè)計(jì),并將此作為品質(zhì)單獨(dú)管理。
2.5.1 什么是品質(zhì)
品質(zhì)是Liferay Portal的外觀,包括題材和色彩設(shè)計(jì)兩個(gè)部分。題材主要影響Portlet窗口的樣式和Portal的整體效果,包括Portlet邊框格式、功能按鈕、Portal頁(yè)面效果等等。色彩設(shè)計(jì)主要影響Portal的CSS樣式效果。
Liferay Portal默認(rèn)定義了多種題材效果和色彩設(shè)計(jì)效果。使用者可以在“品質(zhì)”選項(xiàng)卡中很容易的選擇自己滿意的品質(zhì)。
2.5.2 品質(zhì)和Portlet、Portal的關(guān)系
品質(zhì)跟Portlet和Portal的呈現(xiàn)效果有很大的關(guān)系。通常應(yīng)該根據(jù)Portlet內(nèi)容選擇適當(dāng)?shù)钠焚|(zhì)即題材和色彩設(shè)計(jì)。
題材對(duì)Portal的影響主要體現(xiàn)在背景和整體風(fēng)格上面,以及Portlet和其他功能菜單的布局位置。色彩設(shè)計(jì)主要影響Portal的字體大小以及顏色等效果。
題材主要控制Portlet生成的窗口的樣式效果,包括邊框效果、標(biāo)題樣式等等。色彩主要控制Portlet窗口的字體效果,包括字體大小、字體顏色等等。
選擇合適的題材和色彩設(shè)計(jì)對(duì)于Portal頁(yè)面的整體呈現(xiàn)效果有明顯的影響。如下圖:
圖2.5.2-1 采用不同的色彩設(shè)計(jì)得到的Portal頁(yè)面
圖2.5.2-2 采用不同的題材效果得到的Portal頁(yè)面
2.5.3 定義個(gè)性化的品質(zhì)
用戶登錄Portal系統(tǒng)之后,點(diǎn)擊功能菜單上的“品質(zhì)”,進(jìn)入品質(zhì)定制頁(yè)面。選擇適當(dāng)?shù)念}材和色彩設(shè)計(jì),相應(yīng)的品質(zhì)效果立即生效。
返回桌面查看品質(zhì)效果。
使用者可以在二次開(kāi)發(fā)的時(shí)候定義自己的品質(zhì),只要按照規(guī)范,在部署描述文件中定義可用的品質(zhì),Liferay Portal就可以自動(dòng)調(diào)用。如下圖:
第六節(jié) Liferay Portal的部署描述文件
跟所有的Web應(yīng)
用一樣,Liferay
Portal采用多個(gè)XML部署描述文件,來(lái)初始化部署信息,規(guī)范操作模式,比如Portlet的初始化信息、可用的Portlet列表、Portlet
所屬角色和用戶組等等。通過(guò)這些部署描述文件,Liferay
Portal可以在啟動(dòng)的時(shí)候自動(dòng)加載Portlet,根據(jù)需要生成所需的Portlet頁(yè)面。普通的Web應(yīng)用,也可以很方便的轉(zhuǎn)換成可部署的
Portlet。這種實(shí)現(xiàn)也是JSR168所規(guī)定的。
2.6.1 web.xml
web.xml是所有Java Web應(yīng)用的部署描述文件。其正式的規(guī)范由http://java.sun.com/dtd/web-app_2_3.dtd 定義。
與其他普通Web應(yīng)用相比,Liferay Portal的Portlet 應(yīng)用還需要在web.xml中增加如下內(nèi)容:
a、監(jiān)聽(tīng)器:
這個(gè)要求web 服務(wù)器監(jiān)聽(tīng)所有跟Portlet有關(guān)的請(qǐng)求信息,并將監(jiān)聽(tīng)到的內(nèi)容交給Liferay Portal的Portlet容器處理。
b、Portlet Servlet映射:
其
中,servlet-name為部署的servlet名稱;init-param中定義自己的Portlet類,這個(gè)param-name要跟
portlet.xml、liferay-portlet.xml、liferay-display.xml中的portlet-name節(jié)點(diǎn)值一致。
c、標(biāo)簽庫(kù)映射:
定義了這個(gè)標(biāo)簽庫(kù)映射,在JSP文件中才可以使用諸如<portlet:defineObjects />在內(nèi)的一些特定的Portlet標(biāo)簽。
如果在應(yīng)用中有用到其他的元素,可以按照web.xml規(guī)范加入到相應(yīng)的位置當(dāng)中。
Liferay Portal默認(rèn)的liferay應(yīng)用,由于使用了Struts、Hibernate、Spring在內(nèi)的多個(gè)開(kāi)源框架,所以{PORTAL_HOME}/liferay/WEB-INF/web.xml文件會(huì)相對(duì)復(fù)雜些。
在自定義的Portlet,可以使用getPortletConfig().getInitParameter(“ ”)和getPortletConfig().getParameterNames(“”)兩個(gè)方法來(lái)取得在web.xml中定義的參數(shù)。
2.6.2 portlet.xml
portlet.xml
用來(lái)定義Portlet的諸如部署名稱、初始化參數(shù)、支持模式、resource
bundle等普通的初始化信息,包括:portlet-name、display-name、portlet-class、init-param、
expiration-cathe、supports、portlet-info、security-role-ref等等。其正式的規(guī)范請(qǐng)參考:
http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd
。根目錄為portlet-webapp。
portlet-name:Portlet的規(guī)范名稱,在Portlet應(yīng)用中必須唯一,主要用在Portlet部署和映射中。
display-name:供部署工具調(diào)用的Portlet簡(jiǎn)稱,在Portlet應(yīng)用中必須唯一。
portlet-class:Portlet對(duì)應(yīng)的類,這個(gè)類必須直接或者間接的繼承javax.Portlet.GenericPortlet。
init-param:初始化參數(shù),有成對(duì)的<name>和<value>子元素。通常定義Portlet相應(yīng)模式下可用的JSP頁(yè)面。
expiration-cathe:定義Portlet加載允許最長(zhǎng)的過(guò)期時(shí)間,以秒為單位。-1代表用不過(guò)期。
supports:定義Portlet支持的模式。所有的Portlet都必須支持瀏覽模式。
其他的元素含義請(qǐng)參照:http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd
當(dāng)Web 應(yīng)用中有多個(gè)的Portlet時(shí),可以統(tǒng)一的在Portlet。xml中定義一組的<portlet>元素。2.6.3 liferay-Portlet.xml
定義Portlet默認(rèn)可用的用戶組、默認(rèn)模板、是否支持多個(gè)實(shí)例等,規(guī)范由http://www.liferay.com/dtd/liferay-Portlet-app_3_5_0.dtd 定義。
liferay
-portlet.xml主要包含單獨(dú)或者成組的<portlet>、<role-mapper>。其中,<
portlet>下包含<portlet-name>、<struts-path>、<use-default-
template>、<instanceable>等子元素,<portlet-name>在應(yīng)用中必須唯一,且要跟
portlet.xml相同;<role-mapper>下包含成對(duì)的<role-name>、<role-
link>子元素。具體的元素含義請(qǐng)查看上述dtd定義。
2.6.4 liferay-display.xml
定義
Portlet默認(rèn)的所屬類別。Liferay
Portal對(duì)Portlet實(shí)行按類別管理和劃分用戶權(quán)限。正如我們?cè)谟脩舨呗灾刑岬降模梢灾贫硞€(gè)類別可用的用戶組、用戶和角色,方便權(quán)限控制。
Liferay-display.xml規(guī)范由http://www.liferay.com/dtd/liferay-
display_3_5_0.dtd 定義。
Liferay-display.xml中,<display>下成組的<category>描述了可用的類別,其中portlet元素的id必須與liferay-portlet.xml的portlet-name保持一致,且在應(yīng)用中唯一。
2.6.5 liferay-layout-templates.xml
定
義Portal可用的布局。正如我們?cè)诓季峙c品質(zhì)中提到的那樣,Portal采用tpl文件來(lái)規(guī)劃桌面的布局。liferay-layout-
templates。xml采用成組的layout-template來(lái)構(gòu)建一個(gè)可用的布局列表。此xml的規(guī)范由http:
//www.liferay.com/dtd/liferay-layout-templates_3_6_0.dtd 來(lái)定義。
本文采用Liferay Portal默認(rèn)的布局,暫時(shí)不需要定義自己的布局,故不準(zhǔn)備深入討論。讀者有興趣可以自己查看相關(guān)資料。
2.6.7 liferay-look-and-feel。xml
定
義Portal可用品質(zhì)的模板、圖片、樣式表等等,定義完畢后,Portal可以通過(guò)“布局與品質(zhì)”管理工具來(lái)進(jìn)行品質(zhì)的切換。Liferay-look
-and-feel.xml規(guī)范由http://www.liferay.com/dtd/liferay-look-and-
feel_3_5_0.dtd 定義。
本文采用Liferay Portal默認(rèn)的品質(zhì),不準(zhǔn)備對(duì)品質(zhì)的自定義深入探討。有興趣的讀者可以查看相關(guān)資料。
第二部分 Liferay Portal 二次開(kāi)發(fā)
本部分主要內(nèi)容
GenericPortlet 自定義Portlet類 部署描述文件
第三章 開(kāi)發(fā)自己的Portlet
在
了解了Liferay Portal的基礎(chǔ)架構(gòu),初步體會(huì)Liferay Portal良好的個(gè)性化定制之后,本章將開(kāi)始Liferay
Portal二次開(kāi)發(fā)之旅,講述并擴(kuò)展Portlet的超類GenericPortlet,創(chuàng)建或者修改部署描述文件,構(gòu)建屬于自己的Portlet。
第一節(jié) 重要的基類:GenericPortlet
像Servlet
一樣,編寫的Portlet也必須直接或者間接的擴(kuò)展基類GenericPortlet,這個(gè)是由JCP針對(duì)Portal提出的JSR168規(guī)范定義的。
只要擴(kuò)展自規(guī)范的GenericPortlet,所有的Portlet都可以在支持JSR168規(guī)范的Portal服務(wù)器上運(yùn)行。
GenericPortlet統(tǒng)一定義了可供Portal容器識(shí)別和調(diào)用的方法,包括:
public Init():初始化;
public Init(PortletConfig) :初始化;
public getInitParameter(String):取得在Portlet。xml中定義的初始化參數(shù);
public getInitParameterNames():取得在Portlet。xml中定義的全部初始化參數(shù);
public getPortletConfig():取得包含初始化參數(shù)的配置對(duì)象PortletConfig實(shí)例;
public getPortletContext():取得Portlet上下文;
public getPortletName():取得在Portlet。xml中定義的Portlet名稱。
public getResourceBundle(Locale) :取得Portlet國(guó)際化的Resource Bundle;
protected getTitle(RenderRequest) :取得Portlet的標(biāo)題;
protected doView(RenderRequest,RenderResponse) :Portlet瀏覽模式的處理方法;
protected doEdit(RenderRequest,RenderResponse) :Portlet編輯模式的處理方法;
protected doHelp(RenderRequest,RenderResponse) :Portlet幫助模式的處理方法;
protected doDispatch(RenderRequest,RenderResponse) :Portlet行為分發(fā);
protected processAction(RenderRequest,RenderResponse) :Portlet處理Action Request的方法;
protected render(RenderRequest,RenderResponse):Portal處理Render Request的方法;
public destroy():Portlet銷毀,終止其生命周期。
在Portlet
Portal運(yùn)行的時(shí)候,doView、doEdit、doHelp三個(gè)方法分別被調(diào)用,用以生成Portlet標(biāo)記。同樣也可以調(diào)用Servlet生成
Portlet標(biāo)記,或者不調(diào)用JSP或者Servlet,直接在方法中得到PrintWriter然后用最簡(jiǎn)單的pw.println()打印出內(nèi)容。
這個(gè)過(guò)程類似Servlet,如下:
PrintWriter pw = renderResponse.getWriter();
pw.println(“Hello,world!”);
與Servlet類似,可以使用getInitParamter(String s)得到配置文件中Portlet的初始值,只不過(guò)Servlet在web.xml中,而Portlet在portlet.xml中。
portlet.xml:
<init-param>
<name>jspView</name>
<value>/jsp/view。jsp</value>
</init-param>
針對(duì)如上portlet.xml中的初始化信息,可以采用如下的調(diào)用方式:
SimplePortlet.java:
String jspName = getPortletConfig()。getInitParameter("jspView");
|
第二節(jié) Portlet標(biāo)簽
跟Servlet一樣,Portlet也自
定義了很多靈活的標(biāo)簽。通過(guò)這些標(biāo)簽,可以調(diào)用Portlet內(nèi)部的參數(shù)比如renderResponse、renderRequest、
PortletConfig等,在JSP中跟Portlet通信。當(dāng)然,在使用之前,除了要在web。xml中聲明標(biāo)簽庫(kù)外,還要在JSP的頭部聲明標(biāo)簽
庫(kù)調(diào)用:<%@ taglib uri="http://java。sun。com/Portlet" prefix="Portlet"
%>
3.2.1 defineObjects標(biāo)簽
在使用Portlet典型標(biāo)簽之前,要見(jiàn)聲明<portlet:defineObjects/>,這樣才可以使用其他的標(biāo)簽。defineObjects中間不允許定義任何屬性和包含任何內(nèi)容。
3.2.2 renderURL標(biāo)簽
屬性 值類型 對(duì)應(yīng)值
windowState String minimized
normal
maximized。
PortletMode String view, edit , help
var String
secure
String true
false
創(chuàng)建一個(gè)當(dāng)前RenderURL,當(dāng)訪問(wèn)它時(shí)將使Portlet窗口變?yōu)樽畲蠡癄顟B(tài),模式變?yōu)闉g覽。<portlet:param/>子元素會(huì)在生成的RenderURL中增加number、page兩個(gè)參數(shù)和值。
3.2.3 actionURL標(biāo)簽
屬性 值類型 對(duì)應(yīng)值
windowState String minimized
normal
maximized。
portletMode String view, edit , help
var String
secure
String true
false
<portlet:actionURL windowState="normal" PortletMode="edit">
<portlet:param name="action" value="login"/>
</portlet:actionURL>
創(chuàng)建一個(gè)當(dāng)前ActionURL,當(dāng)訪問(wèn)它時(shí)將使Portlet窗口變?yōu)檎顟B(tài),模式變?yōu)榫庉嫛?lt;Portlet:param/>子元素會(huì)在生成的ActionURL中增加action參數(shù)和值。
renderURL和actionURL兩個(gè)標(biāo)簽在諸如生成form表單的action等方面特別有用。
3.2.4 param標(biāo)簽
屬性 值類型
name String
用在renderURL和actionURL標(biāo)簽內(nèi)部,用來(lái)在生成的URL中增加參數(shù)和值。param標(biāo)簽不運(yùn)行body內(nèi)容存在。
3.2.5 namespace標(biāo)簽
為目前的Portlet產(chǎn)生一個(gè)唯一的Value,防止與其他Portlet或者Portal上面的Value沖突。
上述標(biāo)簽的具體屬性及其約束,請(qǐng)參閱{PORTAL_HOME}/liferay/WEB-INF/tld/liferay-portlet.tld 。
第三節(jié) Portal的對(duì)象
JSR168
給Portal定義了幾個(gè)特別的對(duì)象,用來(lái)操作Portal特有的信息。這些對(duì)象跟Servlet的對(duì)象有點(diǎn)類似,又有點(diǎn)不同。這些對(duì)象都封裝在
{PORTAL_HOME}/common/lib/ext/portlet.jar包中,具體支持實(shí)現(xiàn)要視Portal服務(wù)器而定。
3.3.1 Request對(duì)象
Portlet
中的Request與Servlet的Request一樣接受客戶端發(fā)送的請(qǐng)求,但是與Servlet不同,Portlet的Request分為
Action Request及Render
Request兩種類型,因此Portlet接口中定義了兩種方法用來(lái)處理不同的Request。分別是processAction
(ActionRequest request,ActionResponse response) 和render(RenderRequest
request,RenderResponse response),分別用以處理Action Request和Render
Request。某種意義上來(lái)講,render方法類似Servlet中的service方法,doView,doEdit,doHelp方法又類似
doGet,doPost方法。
①、RenderRequest和ActionRequest
PortletRequest分為
RenderRequest和ActionRequest兩種,分別由renderURL和actionURL來(lái)觸發(fā)。renderURL是
actionURL的一種優(yōu)化。Portlet的開(kāi)發(fā)過(guò)程中盡量使用renderURL而避免actionURL。actionURL適用于有確實(shí)的
Action(行為)的情況下。比如說(shuō),表單form提交后Persistent狀態(tài)的改變、session的改變、perference的修改等等。
renderURL通常用來(lái)處理Portlet的導(dǎo)航。舉個(gè)例子:
使用actionURL:
<%
PortletURL pu = renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
<form name="usrform" method="post" action="<%=pu.toString()%>">
%>
說(shuō)明:表單提交最好使用Post方法而不是Get方法,因?yàn)槟承㏄ortal服務(wù)器可能會(huì)將內(nèi)部狀態(tài)編碼到URL的Query字符串中。
使用renderURL:
<%
PortletURL pu=renderResponse.createRenderURL();
Pu.setParameter("PAGE",Number);
%>
<a href="<%=pu%>">下一頁(yè)</a>
②、renderURL和actionURL的處理方式
當(dāng)客戶端請(qǐng)求是由一個(gè)renderURL觸發(fā)的時(shí)候,Portal服務(wù)器會(huì)調(diào)用該P(yáng)ortal頁(yè)面所有Portlet的render方法。
而當(dāng)客戶端請(qǐng)求是由一個(gè)actionURL觸發(fā)的時(shí)候,Portal服務(wù)器會(huì)先按用該頁(yè)面所有Portlet的processAction方法再調(diào)用render方法。所以,要明確自己到底使用那種URL來(lái)出發(fā)客戶端請(qǐng)求。
③、RenderRequest和ActionRequest的parameter參數(shù)作用范圍
當(dāng)客戶端請(qǐng)求由一個(gè)actionRequest觸發(fā)時(shí),所有parameter參數(shù)的取得都必須在processAction方法中進(jìn)行。比如:
public void processAction(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
//response.setRenderParameter("ACTION",action);
}
public void doView(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
}
如
上processAction方法中,getParameter方法將能成功得到表單中的參數(shù)ACTION所對(duì)應(yīng)的值,因?yàn)槲覀冎溃?dāng)目標(biāo)
Portlet的processAction方法運(yùn)行完后,Portlet
Container將調(diào)用Portal頁(yè)面中所有Portlet的render方法.但是實(shí)際上doView方法中使用getParameter不會(huì)得到
任何值.但是如果把processAction方法中注釋了的一行解除注釋的話,你就可以在doView方法中的得到參數(shù)ACTION對(duì)應(yīng)的值.
這說(shuō)明action request的參數(shù),render方法中不可以直接取到.必須使用了setRenderParameter方法,再次傳遞一次.3.3.2 Response對(duì)象
與Request對(duì)象一樣,
Response對(duì)象也有兩種:RenderResponse和ActionResponse,分別用來(lái)封裝對(duì)應(yīng)的RenderRequest和
ActionRequest的返回信息,比如重定向、窗口狀態(tài)、Portlet模式等。他們兩者的父類PortletResponse擁有
serPorperty和getPorperty兩個(gè)方法,用來(lái)傳遞信息給Portal容器。
ActionResponse主要用來(lái)處理以下功能:
a、 重定向
b、 改變窗口狀態(tài)、Portlet模式
c、 傳遞parameter參數(shù)到RenderRequest中去
RenderResponse主要用來(lái)提供以下功能:
a、 設(shè)置ContentType
b、 得到OutputStream和Writer對(duì)象,用來(lái)輸出頁(yè)面內(nèi)容
c、 Buffering緩沖
d、 設(shè)定Portlet的標(biāo)題,但是必須在Portlet輸出前調(diào)用,否則將被忽略
3.3.3 PortletConfig對(duì)象
和ServletConfig對(duì)象類似,PortletConfig對(duì)象提供對(duì)Portlet初始化信息以及PortletContext對(duì)象存取的方法。
和ServletConfig對(duì)象不同的是,PortletConfig對(duì)象提供對(duì)Portlet的標(biāo)題等資源的I18N支持,可以通過(guò)設(shè)定不同的Resource Bundle文件以提供多種語(yǔ)言支持。
3.3.4 Session對(duì)象
由于容器不同,Portal的Session對(duì)象與Servlet的Session對(duì)象略有不同。
由于Portlet處于Portal服務(wù)器的緣故,Portlet的Session分為Application Scope和Portlet Scope。兩者的區(qū)別在于:
①、Application Scope范圍的Session中保存的對(duì)象,對(duì)于同一個(gè)Portlet應(yīng)用范圍內(nèi)的所有Portlet都是可用的。
②、Portlet Scope范圍的Session中保存的對(duì)象,只對(duì)本Portlet可用,其他Portlet即使在同一個(gè)應(yīng)用中,也不可用。
但是對(duì)于Portlet應(yīng)用來(lái)說(shuō),可以通過(guò)HttpSession來(lái)訪問(wèn)。畢竟Portlet應(yīng)用也是Web應(yīng)用。在使用Session對(duì)象的時(shí)候,最好能明確指出使用的是那個(gè)Scope范圍的Session。比如:
<portlet:actionURL windowState="NORMAL" PortletMode="view" var="pu1">
<portlet:param name="ACTION" value="ApplicationScope"/>
</portlet:actionURL>
<portlet:actionURL windowState="NORMAL" PortletMode="view" var="pu2">
<portlet:param name="ACTION" value="PortletScope"/>
</portlet:actionURL>
這個(gè)JSP創(chuàng)建了兩個(gè)ActionURL,分別產(chǎn)生了兩種PortletSession對(duì)象。
PortletSession ps = req.getPortletSession();
if(ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE)!=null){
app=ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE).
toString();
}
if(ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE)!=null){
Portlet=ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE).
toString();
}
以上代碼根據(jù)需要取得不同Scope范圍的Session對(duì)象值。
同一個(gè)應(yīng)用下,可以直接通過(guò)ServletSession取得PortletSession。APPLICATION_SCOPE范圍下的Session對(duì)象值。
HttpSession se = request.getSession();
if(se.getAttribute("PortletSession.AS")!=null){
app=se.getAttribute("PortletSession.AS");
}
3.3.5 Preference對(duì)象
Preference對(duì)象被設(shè)計(jì)用來(lái)實(shí)現(xiàn)用戶的個(gè)性化設(shè)置,可以幫助用戶對(duì)Portlet進(jìn)行符合用戶需求的顯示定制和行為定制,可以替代部分的數(shù)據(jù)庫(kù)功能。需要指出的是,Preference對(duì)象只是用來(lái)存取簡(jiǎn)單的配置信息,并不能完全替代數(shù)據(jù)庫(kù)應(yīng)用。
Preference對(duì)象對(duì)于配置信息采用鍵-值的形式存取,用戶可以將需要的信息暫時(shí)保存在Preference中。
PortletPreference p= req.getPortletPreferences();
p.setValue("educhina.username","educhina");
p.store();
Preference對(duì)象用來(lái)存取用戶的個(gè)性化信息,所以不同用戶的Preference對(duì)象不能共享,這點(diǎn)跟Session不同。
可以在Portlet.xml中配置Preference信息,如下:
<Portlet-preferences>
<preference>
<name>educhina。username</name>
<value>educhina</value>
<read-only>true</read-only>
</preference>
</Portlet-preferences>
另外,還可以配套使用PreferencesValidator對(duì)象,對(duì)Portlet的Preference在存儲(chǔ)之前進(jìn)行驗(yàn)證,以確保Preference的正確性。
具體規(guī)范可以參照http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd 的<complexType name="preferenceType">部分。第四節(jié) 編寫自己的Portlet類
Liferay
Portal內(nèi)部集成了78個(gè)Portlet,包括直接用PrintWriter輸出的、調(diào)用JSP輸出的、調(diào)用Servlet輸出的,數(shù)據(jù)來(lái)源有直接從
數(shù)據(jù)庫(kù)取得的、通過(guò)Web
Service取得的等等。這里,我們只講述直接用PrintWriter輸出的和調(diào)用JSP輸出的,目的在于講述如何編寫自己的Portlet類。其他
的與此類似,不贅述。
3.4.1 開(kāi)發(fā)環(huán)境
IDE:Eclipse V3.0.1
JDK:V1.4.2_06
ANT:V1.6.2
Tomcat:V5.0(集成在Liferay Portal中)
Liferay Portal:liferay-portal-pro-3.6.0-tomcat
3.4.2 準(zhǔn)備工作
①、安裝JDK V1.4.2_06,在系統(tǒng)環(huán)境變量中增加變量JAVA_HOME,指向JDK安裝目錄。
②、安裝ANT,在系統(tǒng)環(huán)境變量中增加變量ANT_HOME,指向ANT安裝目錄。
③、下載并啟動(dòng)Eclipse V3.0.1.
④、下載并解壓縮liferay-portal-pro-3.6.0-tomcat.zip到某一文件夾,該文件夾即為{PORTAL_HOME}。
⑤、
在Eclipse中新建一個(gè)Java項(xiàng)目,命名為TestPortal,路徑為D:"TestPortal,將{PORTAL_HOME}"common
"ext"portlet.jar以外部jar的形式添加到庫(kù)中。下文中,D:"TestPortal將以{APP_HOME}代稱。在
{APP_HOME}下創(chuàng)建文件夾webapp、deploy、bak。項(xiàng)目缺省輸出文件夾為{APP_HOME}"webapp"WEB-INF"
classes 。
⑥、在{APP_HOME}"webapp"WEB-INF目錄下創(chuàng)建web.xml,內(nèi)容如下:
<?xml version="1。0"?>
<!DOCTYPE
web-app PUBLIC "-//Sun Microsystems, Inc。//DTD Web Application 2。3//EN"
"http://java。sun。com/dtd/web-app_2_3。dtd">
<web-app>
<display-name>TestPortal</display-name>
</web-app>
⑦、在{APP_HOME}"webapp"WEB-INF下創(chuàng)建tld文件夾,將{PORTAL_HOME}"liferay"WEB-INF"tld/liferay-portlet.tld拷貝到創(chuàng)建的tld文件夾下,備用。
⑧、新建一個(gè)Java包c(diǎn)om.educhina.portal 。
3.4.3 HelloWorldPortlet
HelloWorldPortlet
類計(jì)劃用單純的PrintWriter輸出Portlet標(biāo)記片斷。在包c(diǎn)om.educhina.portal下新建Java類
HelloWorldPortlet,這個(gè)類必須擴(kuò)展自javax.Portlet.GenericPortlet類。設(shè)計(jì)讓
HelloWorldPortlet支持瀏覽和編輯兩種模式,所以HelloWorldPortlet重寫doView和doEdit方法。簡(jiǎn)單的代碼如
下:
package com.educhina.portal;
import java.io.IOException;
import javax.Portlet.GenericPortlet;
import javax.Portlet.PortletException;
import javax.Portlet.RenderRequest;
import javax.Portle.RenderResponse;
public class HelloWorldPortlet extends GenericPortlet{
public void doView(RenderRequest req, RenderResponse res)
throws IOException, PortletException {
res.setContentType("text/html");
res.getWriter().println("HelloWorld!");
}
public void doEdit(RenderRequest req,RenderResponse res)
throws IOException,PortletException {
res.setContentType("text/html");
res.getWriter().println("HelloWorld!");
}
}
doView和doEidt方法從RenderRequest取得PrintWriter對(duì)象,直接輸出一個(gè)String字符“HelloWorld!”。這個(gè)String字符將作為HelloWorldPortlet的片斷內(nèi)容。
3.4.4 HelloJSPPortlet
HelloJSPPortlet
類計(jì)劃調(diào)用外部JSP輸出。同樣的,HelloJSPPortlet也要擴(kuò)展自GenericPortlet類。HelloJSPPortlet調(diào)用
getPortletConfig().getInitParameter("..")方法,取得在Portlet。xml中配置的view-jsp和
edit-jsp參數(shù)值,以此確定JSP頁(yè)面的具體位置。然后調(diào)用PortletRequestDispatcher的include方法,將JSP頁(yè)面
加載到RenderResponse。代碼如下:
package com.educhina.portal;
import java.io.IOException;
import javax.Portlet.GenericPortlet;
import javax.Portlet.PortletException;
import javax.Portlet.PortletRequestDispatcher;
import javax.Portlet.RenderRequest;
import javax.Portlet.RenderResponse;
public class HelloJSPPortlet extends GenericPortlet{
public void doView(RenderRequest req, RenderResponse res)
throws IOException, PortletException {
res.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view-jsp");
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);
rd.include(req,res);
}
public void doEdit(RenderRequest req,RenderResponse res)
throws IOException,PortletException {
res.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("edit-jsp");
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);
rd.include(req,res);
}
}
在{APP_HOME}/webapp目錄下創(chuàng)建view.jsp和edit.jsp,view.jsp代碼如下,edit.jsp類似:
<table cellpadding="8" cellspacing="0" width="100%">
<tr>
<td>
<font class="Portlet-font" style="font-size: x-small;">
This is a <b>Sample JSP Portlet</b> used in viewing model。 Use this as a quick way to include JSPs。
</font>
</td>
</tr>
</table>
JSP
文件不能包含關(guān)于HTML的<head>、<body>、<html>的信息,只能包含原來(lái)位于<
body></body>內(nèi)部的HTML內(nèi)容。那些<head>、<body>、<html>信
息由Portal頁(yè)面來(lái)提供。
只有在JSP頁(yè)面中使用<%@ taglib
uri="http://java.sun.com/portlet" prefix="portlet"
%>和<portlet:defineObjects/>,JSP頁(yè)面才可以直接操作Portlet的一些變量,比如:
renderResponse、renderRequest、portletConfig。
|
第五節(jié) 修改Web部署描述文件
正如2.6.1所指出的那樣,要保證
Portlet能夠在Liferay
Portal成功部署,必須對(duì)web.xml進(jìn)行必要的修改,添加Portlet監(jiān)聽(tīng)器、Servlet映射、Portlet標(biāo)簽庫(kù)。在先前
web.xml的<display>節(jié)點(diǎn)下增加如下內(nèi)容:
<listener>
<listener-class>com.liferay.portal.servlet.PortletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>HelloWorldPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>com.educhina.portal.HelloWorldPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldPortlet</servlet-name>
<url-pattern>/HelloWorldPortlet/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HelloJSPPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>com.educhina.portal.HelloJSPPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloJSPPortlet</servlet-name>
<url-pattern>/HelloJSPPortlet/*</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>http://java.sun.com/Portlet</taglib-uri>
<taglib-location>/WEB-INF/tld/liferay-Portlet.tld</taglib-location>
</taglib>
其
中,<listener>節(jié)點(diǎn)是增加一個(gè)監(jiān)聽(tīng)器,以便Liferay
Portal監(jiān)聽(tīng)所有針對(duì)Portlet的操作。<servlet>以及<servlet-mapping>是將上述兩個(gè)
Portlet類加入Servlet容器中。Portlet類實(shí)質(zhì)上也是Servlet。<tablib>是將Liferay
Portal標(biāo)簽庫(kù)加入列表中,以便JSP調(diào)用。第六節(jié) 創(chuàng)建Liferay Portal部署描述文件
修改完web.xml之后,還要?jiǎng)?chuàng)建2.6所說(shuō)的三個(gè)Portlet部署描述文件:portlet.xml、liferay-portlet.xml、liferay-display.xml。
①、portlet.xml
portlet.xml
定義Portlet的初始化信息。這里,我們?cè)趐ortlet.xml中增加兩個(gè)Portlet節(jié)點(diǎn),分別代表HelloWorldPortlet和
HelloJSPPortlet。其中,HelloWorldPortlet支持PringWriter輸出,HelloJSPPortlet支持JSP
輸出;兩者都支持瀏覽和編輯兩種模式。HelloJSPPortlet需要定義兩個(gè)init參數(shù),告訴系統(tǒng)JSP文件的位置。
<portlet>
<portlet-name>HelloWorldPortlet</portlet-name>
<display-name>HelloWorldPortlet</display-name>
<portlet-class>com.educhina.portal.HelloWorldPortlet</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<Portlet-mode>edit</Portlet-mode>
</supports>
<portlet-info>
<title>HelloWorldPortlet</title>
<short-title>HelloWorldPortlet</short-title>
<keywords>HelloWorldPortlet</keywords>
</portlet-info>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
<portlet>
<portlet-name>HelloJSPPortlet</portlet-name>
<display-name>HelloJSPPortlet</display-name>
<portlet-class>com。Educhina.portal.HelloJSPPortlet</portlet-class>
<init-param>
<name>view-jsp</name>
<value>/view。jsp</value>
</init-param>
<init-param>
<name>edit-jsp</name>
<value>/edit。jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<Portlet-mode>edit</Portlet-mode>
</supports>
<portlet-info>
<title>HelloJSPPortlet</title>
<short-title>HelloJSPPortlet</short-title>
<keywords>HelloJSPPortlet</keywords>
</portlet-info>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
②、liferay-Portlet.xml
Liferay-Portlet.xml主要定義Portlet的模板、實(shí)例總數(shù)、是否允許重復(fù)定義等。同樣的,我們?cè)黾恿藘蓚€(gè)<Portlet>節(jié)點(diǎn),代表HelloWorldPortlet和HelloJSPPortlet。
<?xml version="1。0"?>
<!DOCTYPE
liferay-Portlet-app PUBLIC "-//Liferay//DTD Portlet Application
3。5。0//EN"
"http://www。liferay。com/dtd/liferay-Portlet-app_3_5_0。dtd">
<liferay-portlet-app>
<portlet>
<Portlet-name>HelloWorldPortlet</Portlet-name>
<struts-path>HelloWorldPortlet</struts-path>
<use-default-template>true</use-default-template>
<instanceable>true</instanceable>
</portlet>
<portlet>
<Portlet-name>HelloJSPPortlet</Portlet-name>
<struts-path>HelloJSPPortlet</struts-path>
<use-default-template>true</use-default-template>
<instanceable>true</instanceable>
</portlet>
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
</role-mapper>
<role-mapper>
<role-name>guest</role-name>
<role-link>Guest</role-link>
</role-mapper>
<role-mapper>
<role-name>power-user</role-name>
<role-link>Power User</role-link>
</role-mapper>
<role-mapper>
<role-name>user</role-name>
<role-link>User</role-link>
</role-mapper>
</liferay-portlet-app>
③、liferay-display.xml
liferay-display.xml定義Portlet所屬類別。Liferay Portal默認(rèn)定義了一個(gè)category.test類別,這里,我們將HelloWorldPortlet和HelloJSPPortlet歸屬到category.test。
<?xml version="1。0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 3。5。0//EN" "http://www。liferay。com/dtd/liferay-display_3_5_0。dtd">
<display>
<category name="category。test">
<Portlet id="HelloWorldPortlet" />
<Portlet id="HelloJSPPortlet" />
</category>
</display>
至此,一個(gè)簡(jiǎn)單的Portlet就開(kāi)發(fā)完成了。接下來(lái),我們把它部署到Liferay Portal上。第三部分 Liferay Portal部署
本部分主要內(nèi)容
Portlet部署 ANT 管理Portlet
第四章 部署自己的Portlet
Liferay
Portal跟Tomcat5.0集成在一起,從本質(zhì)上講,liferay-portal-pro-3.6.0-tomcat.zip是一個(gè)Tomcat
壓縮包,只是其中將liferay作為默認(rèn)應(yīng)用,并將跟Portlet有關(guān)的操作都交給liferay應(yīng)用處理而已。因此,Liferay
Portal支持所有針對(duì)Tomcat5.0的部署方式,包括:手動(dòng)部署、Ant部署,并且支持熱部署。
第一節(jié) 手動(dòng)部署
手動(dòng)部署可以采用拷貝文件夾、war部署、編寫部署文件三種方式:
①、
拷貝文件夾:與單純的Tomcat一樣,我們可以將{APP_HOME}"webapp目錄拷貝到{PORTAL_HOME}"webapps"下,該
webapp目錄名為TestPortal。啟動(dòng)Liferay
Portal(雙擊{PORTAL_HOME}"bin"startup。bat)即可。
②、war部署:或者將{APP_HOME}"
webapp打包成TestPortal.war,拷貝war到{PORTAL_HOME}"webapps"下,啟動(dòng)Liferay
Portal,讓Tomcat自動(dòng)解壓。在命令行模式下切換到{APP_HOME}"webapp目錄,執(zhí)行 jar cvf
TestPortal.war * 。
③、編寫部署文件:
{PORTAL_HOME}"conf"Catalina"localhost目錄下,創(chuàng)建TestPortal.xml文件,內(nèi)容如下:
<Context path="/TestPortal" docBase="D:"TestPortal"webapp" debug="0" reloadable="true" crossContext="true">
</Context>
部署成功后,登錄Liferay Portal,可以在桌面底部的下拉列表中看到HelloWorldPortlet和HelloJSPPortlet兩個(gè)Portlet。將它們添加到桌面中。
第二節(jié) Ant自動(dòng)部署
確保之前已經(jīng)安裝Apache Ant,并正確添加ANT_HOME到系統(tǒng)環(huán)境變量。
①、拷貝之前打包的TestPortlet.war到{APP_HOME}/deploy目錄;
②、
從http://prdownloads。sourceforge。net/lportal/Portlet-deployer-3。6。0。xml
下載Portlet-deployer-3.6.0.xml 到{APP_HOME}"deploy,改名為build。xml以便Ant自動(dòng)加載;
③、確保JDK1.4.2和Ant 1.6安裝成功,并配置到系統(tǒng)環(huán)境變量;
④、確保Tomcat或者其他服務(wù)器已經(jīng)正確安裝,或者Liferay Portal正常安裝。
編
輯build.xml,使其只想你的應(yīng)用服務(wù)器或者Servlet容器。比如,如果你安裝JBoss+Jetty到/opt/liferay目錄,那么編
輯build.xml,確保只有JBoss+Jetty部分沒(méi)有被注釋,修改app.server屬性為/opt/liferay。
Build.xml默認(rèn)是開(kāi)啟JBoss+Jetty部分,本文采用的是Tomcat集成包,所以將JBoss+Jetty部分注釋掉,開(kāi)始Tomcat部分。修改app.server.dir屬性,指向{PORTAL_HOME}。如下圖:
⑤、
命令行切換到到{APP_HOME}/deploy目錄,執(zhí)行 ant deploy
,系統(tǒng)會(huì)自動(dòng)將TestPortal。war解壓,必要時(shí)修改web.xml、portlet.xml等部署文件,將解壓后的TestPortal文件夾
拷貝到{PORTAL_HOME}"webapps目錄下。
啟動(dòng)Liferay Portal之前,建議先確認(rèn)修改后的web.xml、portlet.xml等部署文件是否正確。
第三節(jié) 加入Liferay Portal自有列表
之
前我們提到過(guò),Liferay
Portal集成了78個(gè)默認(rèn)的Portlet應(yīng)用。這些應(yīng)用都通過(guò){PORTAL_HOME}"liferay"WEB-INF"目錄下的
portlet.xml、liferay-portlet.xml、liferay-display。xml描述。我們只要更改這些描述文件,就可以將我
們自己的應(yīng)用加入到Liferay Portal的Portlet列表中了,效果跟手動(dòng)部署和Ant自動(dòng)部署一樣。
①、拷貝{APP_HOME}"webapp目錄的內(nèi)容到{PORTAL_HOME}"liferay"html"Portlet目錄下,更改文件夾名稱為TestPortal。
②、將TestPortal"WEB-INF"classes文件夾剪切到{PORTAL_HOME}"liferay"WEB-INF目錄下。
③、
將TestPortal"WEB-INF"web。xml中<servlet>、<servlet-mapping>的內(nèi)容合并
到{PORTAL_HOME}"liferay"WEB-INF"web.xml中。刪除TestPortal"WEB-INF"web.xml。
④、
將TestPortal"WEB-INF"Portlet.xml中關(guān)于HelloWorldPortlet和HelloJSPPortlet的<
portlet>的內(nèi)容合并到{PORTAL_HOME}"liferay"WEB-INF"portlet.xml中。刪除TestPortal
"WEB-INF" portlet.xml。
⑤、將TestPortal"WEB-INF"liferay-portlet.xml中關(guān)于
HelloWorldPortlet和HelloJSPPortlet的<portlet>的內(nèi)容合并到{PORTAL_HOME}"
liferay"WEB-INF"liferay-portlet.xml中。刪除TestPortal"WEB-INF"liferay-
portlet.xml。
⑥、將TestPortal"WEB-INF"liferay-display.xml中關(guān)于
HelloWorldPortlet和HelloJSPPortlet的<portlet>的內(nèi)容合并到{PORTAL_HOME}"
liferay"WEB-INF"liferay- display.xml中。刪除TestPortal"WEB-INF" liferay-
display.xml。
這個(gè)方法比較復(fù)雜,而且不容易擴(kuò)展和調(diào)試,通常不建議采用。
第四節(jié) 普通Java Web應(yīng)用轉(zhuǎn)化為Portlet應(yīng)用
隨
著開(kāi)發(fā)的深入,我們希望能夠?qū)⒃瓉?lái)的Java Web應(yīng)用遷移到Liferay Portal,構(gòu)建真正的企業(yè)門戶。Liferay
Portal靈活的二次開(kāi)發(fā)機(jī)制,允許用戶將各種各樣的內(nèi)容集成到Portal平臺(tái)上來(lái),消除信息孤島。將一個(gè)Java
Web應(yīng)用轉(zhuǎn)化為Portlet應(yīng)用的步驟如下:
①、撰寫擴(kuò)展自GenericPortlet的Portlet和JSP頁(yè)面。這個(gè)Portlet可以使用PrintWriter輸出或者調(diào)用JSP頁(yè)面輸出方式。通常,如果Java Web應(yīng)用是采用MVC三層模式,那么只需要更改View層就可以了。
②、修改web.xml,增加2。6。1所述的Portlet監(jiān)聽(tīng)器和Portlet標(biāo)簽庫(kù),增加針對(duì)上步驟所寫的servlet和servlet映射。
<servlet>
<servlet-name>yourPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>full.name.of.yourPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>yourPortlet</servlet-name>
<url-pattern>/yourPortlet/*</url-pattern>
</servlet-mapping>
③、創(chuàng)建portlet.xml,增加相應(yīng)的Portlet定義信息,規(guī)范參考2.6.2。
④、創(chuàng)建liferay-portlet.xml,增加相應(yīng)的Portlet定義信息,規(guī)范參考2.6.3。
⑤、創(chuàng)建liferay-display.xml,增加相應(yīng)的Portlet類別定義信息,規(guī)范參考2.6.4。
⑥、
拷貝portlet.jar和liferay-Portlet.tld到當(dāng)前應(yīng)用。其中,portlet.jar是Portlet
API包,作用類似servlet-api.jar,位于{PORTAL_HOME}"common"lib"ext"liferay-
portlet.tld是Liferay Portal提供的Portlet標(biāo)簽庫(kù)。
⑦、選擇適當(dāng)?shù)牟渴鸱绞剑瑢⑿薷暮蟮腏ava Web應(yīng)用部署到Portlet平臺(tái)上。第四部分 附錄
本部分主要內(nèi)容
資源網(wǎng)站 Portlet范例 參考資料 后序
第五章 相關(guān)資源
作為一個(gè)開(kāi)源的門戶產(chǎn)品,Liferay Portal已經(jīng)比較成熟,有比較齊全的文檔。隨著應(yīng)用的深入,開(kāi)源免費(fèi)的中文化文檔也在陸續(xù)出現(xiàn)。
第一節(jié) 資源網(wǎng)站
Liferay Portal 官方網(wǎng)站:http://www.liferay.com
Liferay Portal 中文網(wǎng)站:http://www.liferay.cn
Liferay Portal 論壇:http://forums.liferay.com
Tracker : http://support.liferay.com
郵件列表:http://sourceforge.net/mailarchive/forum.php?forum=lportal-development
JavaLobby專題:http://www.javalobby.org/articles/liferay/
OSQS專題:http://cstsolaris.cst.nait.ab.ca/ist410/gerry/liferay/index.jsp
Leonardsoko1專題:http://www.leonardsokol.com/liferay/
Developer專題:http://www.developer.com/java/web/article.php/10935_3372881_1
第二節(jié) 示例
Liferay
Portal隨程序包提供了豐富的documentation,其中的Portlet Examples對(duì)Portal內(nèi)置的Hello
World、IFrame、Calendar、Message Boards、Mail五個(gè)Portlet進(jìn)行了比較詳細(xì)的解說(shuō)。啟動(dòng)Liferay
Portal后,瀏覽這里:
http://localhost/web/guest/documentation/development/Portlet
另
外,Liferay Portal還在官方網(wǎng)站上提供了Sample Layout Template、Sample Portlet、Sample
Themes供下載。其中,Sample Portlet包括Sample JSP Portlet、Sample Struts
Portlet、Sample JSF SUN Portlet、Sample JSF MyFaces Portlet。瀏覽這里:
http://localhost/web/guest/downloads/sample_Portlet
第六章 參考資料
①、文檔
《JSR168 PORLET標(biāo)準(zhǔn)手冊(cè)漢化整理》 作者:Jini等
《Portlet應(yīng)用開(kāi)發(fā)(JSR168)》 作者:Terry Lee
《(原創(chuàng)翻譯)Liferay-Portal架構(gòu)》 作者:eamoi
②、網(wǎng)站
http://www.liferay.com
http://www.liferay.cn
后序
研
究Liferay
Portal屬于半路出家。從開(kāi)始到本文完成,倆月有余。作為一個(gè)開(kāi)源的Portal產(chǎn)品,Liferay的確值得稱許,雖然還有不少bug。在本文截稿
的時(shí)候,Liferay Portal
V3.6.1已經(jīng)發(fā)版,新版本在拖拉Portlet、Spring遠(yuǎn)程傳輸和布局熱部署方面有比較大的提升。本文不會(huì)就此終結(jié),暫稱V1.0,作為前段工
作的總結(jié)。本文的用戶策略部分參考了同事Kevin的文檔,特此感謝。
PS:寫文章真的很費(fèi)腦筋。
(完)