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