什么是Portlet ?作者:Sunil Patil譯者:observer版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明作者:Sunil Patil;
observer原文地址:
http://www.onjava.com/pub/a/onjava/2005/10/19/challenging-java-dominance.html中文地址:
http://www.matrix.org.cn/resource/article/44/44029_Portlet.html關(guān)鍵詞: Portlet Java
Portlets “Portlets
是一種Web組件-就像servlets-是專(zhuān)為將合成頁(yè)面里的內(nèi)容聚集在一起而設(shè)計(jì)的。通常請(qǐng)求一個(gè)portal頁(yè)面會(huì)引發(fā)多個(gè)portlets被調(diào)
用。每個(gè)portlet都會(huì)生成標(biāo)記段,并與別的portlets生成的標(biāo)記段組合在一起嵌入到portal頁(yè)面的標(biāo)記內(nèi)。”(摘自Portlet規(guī)范,
JSR 168)
本文探討了以下內(nèi)容:
1. Portal頁(yè)面的元素
2. Portal是什么?
3. Portlets是什么?
4. 開(kāi)發(fā)“Hello World” Portlet
5. 在Pluto上部署HelloWorld Portlet
6. 如何創(chuàng)建Portal頁(yè)面
7. 結(jié)束語(yǔ)
8. 資源 Portlet規(guī)范將portlet定義為一種“基于Java技術(shù)的web組件,由處理請(qǐng)求和生成動(dòng)態(tài)內(nèi)容的portlet容器管理”。這段話聽(tīng)起來(lái)是不是有些費(fèi)解?本文將說(shuō)明portlets是什么以及能用它們做什么。
圖1顯示了在訪問(wèn)一個(gè)portal服務(wù)器時(shí)瀏覽器中頁(yè)面的樣子。

圖1 典型的portal服務(wù)器的頁(yè)面(點(diǎn)擊查看原圖)
如果仔細(xì)查看瀏覽器里的頁(yè)面,就會(huì)看到頁(yè)面是由不同的“窗口”組成的。一個(gè)窗口用于刷新天氣,另一個(gè)用于新聞,還有一個(gè)用于刷新股價(jià),等等。這里的每一
個(gè)窗口都代表了一個(gè)portlets。如果看得再仔細(xì)些,還會(huì)發(fā)現(xiàn)每個(gè)窗口都有一個(gè)標(biāo)題條和一些按鈕,包括最小化和最大化按鈕。
在系
統(tǒng)里,這些窗口是相互獨(dú)立開(kāi)發(fā)、各不同的應(yīng)用。新聞portlet的開(kāi)發(fā)者創(chuàng)建應(yīng)用并打包成war格式的文件,隨后portal服務(wù)器的管理員在服務(wù)器上
部署該war文件并創(chuàng)建頁(yè)面,接下來(lái)每個(gè)用戶(hù)會(huì)選擇在他的頁(yè)面里有哪些應(yīng)用。例如,如果用戶(hù)對(duì)股價(jià)不感興趣而對(duì)體育感興趣,他可以用“體育”窗口替換“股
價(jià)”窗口。
Portlet技術(shù)需要學(xué)習(xí)許多新概念,本文不可能全都涵蓋,因此本文分為兩部分。在第一部分里我們?cè)敿?xì)說(shuō)明portals和portlets,并開(kāi)發(fā)一個(gè)簡(jiǎn)單的“Hello World”portlet;在第二部分我們將探討一些高級(jí)主題。
我們將用Apache的Pluto服務(wù)器(Portlet API 1.0規(guī)范的參考實(shí)現(xiàn))來(lái)測(cè)試我們的示例portlets,我們還會(huì)花些時(shí)間探討如何安裝和使用Pluto服務(wù)器。
Portal頁(yè)面的元素圖2顯示了Portal頁(yè)面的各種元素。

圖2 portal頁(yè)面的元素
每個(gè)portlet頁(yè)面由一個(gè)或多個(gè)portlet窗口組成,每個(gè)portlet窗口又分為兩部分:一個(gè)是外觀,它決定了portlet窗口的標(biāo)題條、控制和邊界的樣式;另一個(gè)是portlet段,它由portlet應(yīng)用填充。
Portal服務(wù)器決定了portal頁(yè)面的整體觀感,像標(biāo)識(shí)、標(biāo)題條顏色、控制圖標(biāo)等。通過(guò)修改幾個(gè)JSP和css模板文件就可以改變portal的整個(gè)觀感。我們將在“如何創(chuàng)建portal頁(yè)面”部分對(duì)此做深入討論。
Portal是什么?
在了解portlet之前有必要先了解portal。在Portlet規(guī)范里是這樣講的:“portal是一種web應(yīng)用,通常用來(lái)提供個(gè)性化、單次登
錄、聚集各個(gè)信息源的內(nèi)容,并作為信息系統(tǒng)表現(xiàn)層的宿主。聚集是指將來(lái)自各個(gè)信息源的內(nèi)容集成到一個(gè)web頁(yè)面里的活動(dòng)”。
Portal的功能可以分為三個(gè)主要方面:
1. Portlet
容器:Portlet容器與servlet容器非常類(lèi)似,所有的portlet都部署在portlet容器里,portlet容器控制portlet的生
命周期并為其提供必要的資源和環(huán)境信息。Portlet容器負(fù)責(zé)初始化和銷(xiāo)毀portlets,向portlets傳送用戶(hù)請(qǐng)求并合成響應(yīng)。
2. 內(nèi)容聚集:Portlet規(guī)范中規(guī)定portal的主要工作之一是聚集由各種portlet應(yīng)用生成的內(nèi)容,我們將在“如何創(chuàng)建Portal頁(yè)面”部分對(duì)此做進(jìn)一步討論。
3. 公共服務(wù):portlet服務(wù)器的一個(gè)強(qiáng)項(xiàng)是它所提供的一套公共服務(wù)。這些服務(wù)并不是portlet規(guī)范所要求的,但portal的商業(yè)實(shí)現(xiàn)版本提供了豐富的公共服務(wù)以有別于它們的競(jìng)爭(zhēng)者。在大部分實(shí)現(xiàn)中都有望找到的幾個(gè)公共服務(wù)有:
o 單次登錄:只需登錄portal服務(wù)器一次就可以訪問(wèn)所有其它的應(yīng)用,這意味著你無(wú)需再分別登錄每一個(gè)應(yīng)用。例如一旦我登錄了我的intranet網(wǎng)站,我就能訪問(wèn)mail應(yīng)用、IM消息應(yīng)用和其它的intranet應(yīng)用,不必再分別登錄這些應(yīng)用。
Portal服務(wù)器會(huì)為你分配一個(gè)通行證庫(kù)。你只需要在mail應(yīng)用里設(shè)定一次用戶(hù)名和密碼,這些信息將以加密的方式存儲(chǔ)在通行證庫(kù)中。在你已登錄到
intranet網(wǎng)站并要訪問(wèn)mail應(yīng)用的時(shí)候,portal服務(wù)器會(huì)從通行證庫(kù)中讀取你的通行證替你登錄到mail服務(wù)器上。你對(duì)其它應(yīng)用的訪問(wèn)也將
照此處理。
o個(gè)性化:個(gè)性化服務(wù)的基本實(shí)現(xiàn)使用戶(hù)能從兩方面?zhèn)€性化她的頁(yè)面:第一,用戶(hù)可以根據(jù)她的自身喜好決定標(biāo)題條的顏
色和控制圖標(biāo)。第二,用戶(hù)可以決定在她的頁(yè)面上有哪些portlets。例如,如果我是個(gè)體育迷,我可能會(huì)用一個(gè)能提供我鐘愛(ài)球隊(duì)最新信息的
portlet來(lái)取代股票和新聞portlets。
一些在個(gè)性化服務(wù)方面領(lǐng)先的商業(yè)實(shí)現(xiàn)版本允許你建立為用戶(hù)顯示什么樣的應(yīng)用所
依據(jù)的標(biāo)準(zhǔn)(如收入和興趣)。在這種情況下,可以設(shè)定一些像“對(duì)任何收入為X的用戶(hù)顯示饋贈(zèng)商品的portlet”和“對(duì)任何收入為X的用戶(hù)顯示打折商品
的portlet”這樣的商業(yè)規(guī)則。
此外還有一些公共服務(wù),比如機(jī)器翻譯,是由portal服務(wù)器將portlet生成的內(nèi)容翻譯為用戶(hù)要求的語(yǔ)言。大部分的商業(yè)portal服務(wù)器都支持手持設(shè)備訪問(wèn)并具有針對(duì)不同的瀏覽終端生成不同內(nèi)容的能力。
Portlets是什么? 與servlets類(lèi)似,portlets是部署在容器內(nèi)用來(lái)生成動(dòng)態(tài)內(nèi)容的web組件。從技術(shù)角度講portlet是一個(gè)實(shí)現(xiàn)了javax.portlet.Portlet接口的類(lèi),它被打包成war文件格式部署到portlet容器里。
Portlets在以下方面與servlets相似:
1. portlets由特定的容器管理。
2. portlets生成動(dòng)態(tài)內(nèi)容。
3. portlet的生命周期由容器管理。
4. portlets通過(guò)請(qǐng)求/響應(yīng)模式與web客戶(hù)端交互。
Portlets在以下方面與servlets相異:
1. portlets只能生成標(biāo)記段,而不是整個(gè)文檔。
2. portlets沒(méi)有可供直接訪問(wèn)的URL地址。不過(guò)你還是能夠讓別人通過(guò)URL訪問(wèn)到portlet,你可以把包含該portlet的頁(yè)面的URL發(fā)給他。
3. portlets
不能隨意地生成內(nèi)容,這是因?yàn)閜ortlet生成的內(nèi)容最終要成為portal頁(yè)面的一部分。如果portal服務(wù)器要求的是html/text類(lèi)型,那
么所有的portlets都應(yīng)生成html/text類(lèi)型的內(nèi)容。再比方說(shuō),如果portal服務(wù)器要求的是WML類(lèi)型,那么所有的portlets都應(yīng)
生成WML類(lèi)型的內(nèi)容。
portlets還提供了一些附加的功能:
1. 設(shè)置參數(shù)的持久化存儲(chǔ):portlets提供了一個(gè)PortletPreferences對(duì)象用來(lái)保存用戶(hù)的設(shè)置參數(shù)。這些參數(shù)被存入一個(gè)持久化數(shù)據(jù)庫(kù),這樣服務(wù)器重啟后數(shù)據(jù)依然有效。開(kāi)發(fā)者不必關(guān)心這些數(shù)據(jù)存儲(chǔ)的具體實(shí)現(xiàn)機(jī)制。
2.
請(qǐng)求處理:portlets提供了更為細(xì)粒度的請(qǐng)求處理。對(duì)于用戶(hù)在portlet上動(dòng)作時(shí)向該portlet發(fā)出的請(qǐng)求(一種稱(chēng)為活躍期的狀態(tài)),或者
因用戶(hù)在其它portlet上動(dòng)作而引發(fā)的刷新頁(yè)面請(qǐng)求,Portal服務(wù)器提供了兩種不同的回調(diào)方法來(lái)處理。
3. Portlet
模式:portlets用模式的概念來(lái)表示用戶(hù)在做什么。在使用mail應(yīng)用的時(shí)候,你可能會(huì)用它來(lái)讀信、寫(xiě)信或檢查信件――這些都是mail應(yīng)用的預(yù)定
功能,Portlets通常以VIEW模式提供這些功能。但還有一些活動(dòng),像指定刷新時(shí)間或(重新)設(shè)置用戶(hù)名和密碼,這些活動(dòng)允許用戶(hù)定制應(yīng)用的行為,
因此它們用的是EDIT模式。Mail應(yīng)用的幫助功能用的是HELP模式。
如果仔細(xì)想想其實(shí)這里面并沒(méi)有什么新東西,它們反而大部分都是普通的業(yè)務(wù)需求。Portlet規(guī)范的作用在于它提供了一個(gè)抽象層,這才是它對(duì)所有與之相關(guān)的人-最終用戶(hù)、開(kāi)發(fā)者和管理員-的價(jià)值所在。
作為一個(gè)開(kāi)發(fā)者,我會(huì)將所有與VIEW模式有關(guān)的業(yè)務(wù)邏輯放入doView()方法,將與應(yīng)用配置有關(guān)的業(yè)務(wù)邏輯放入doEdit()方法,將與幫助有關(guān)的邏輯放入doHelp()方法
這就簡(jiǎn)化了管理員對(duì)portlet應(yīng)用的訪問(wèn)控制管理,因?yàn)樗恍韪淖僷ortlet的訪問(wèn)權(quán)限就能決定用戶(hù)能做什么。例如,如果mail應(yīng)用的一個(gè)用戶(hù)能夠在EDIT模式下設(shè)定用戶(hù)名和密碼,那么就可以斷定他具有EDIT模式訪問(wèn)權(quán)限。
不妨考慮這樣一種情形:我是一個(gè)intranet網(wǎng)站的管理員,我的公司買(mǎi)了一個(gè)能顯示新聞信息的第三方portlet應(yīng)用,該應(yīng)用允許用戶(hù)指定跟蹤新
聞更新的URL地址,我想借助它為用戶(hù)顯示公司的內(nèi)部新聞。另一個(gè)需求是我不想讓用戶(hù)通過(guò)該應(yīng)用來(lái)跟蹤任何其它的新聞信息來(lái)源。作為管理員,我可以為所有
的用戶(hù)指定一個(gè)用于內(nèi)部新聞更新的URL地址,同時(shí)通過(guò)改變portlet應(yīng)用的部署描述符來(lái)取消其它人修改該地址的權(quán)限。
由于所有的portlet應(yīng)用都具有相似的UI界面,因此采用portlets可使網(wǎng)站對(duì)最終用戶(hù)更具吸引力。如果她想閱讀任何一個(gè)應(yīng)用的幫助信息,她可以點(diǎn)擊幫助按鈕;她也知道點(diǎn)擊編輯按鈕能讓她進(jìn)入應(yīng)用的配置屏。標(biāo)準(zhǔn)化的用戶(hù)界面使你的portlet應(yīng)用更引人。
4.
窗口狀態(tài):窗口狀態(tài)決定了portal頁(yè)面上留給portlet生成內(nèi)容的空間。如果點(diǎn)擊最大化按鈕,portlet將占據(jù)整個(gè)屏幕,成為用戶(hù)唯一可用的
portlet;而在最小化狀態(tài),portlet只顯示為標(biāo)題條。作為開(kāi)發(fā)者應(yīng)當(dāng)根據(jù)可用空間的大小來(lái)定做內(nèi)容。
5. 用
戶(hù)信息:通常portlets向發(fā)出請(qǐng)求的用戶(hù)提供個(gè)性化的內(nèi)容,為了能更加行之有效,portlets需要訪問(wèn)用戶(hù)的屬性信息,如姓名、email、電
話等。Portlet
API為此提供了用戶(hù)屬性的概念,開(kāi)發(fā)者能夠用標(biāo)準(zhǔn)的方式訪問(wèn)這些屬性,并由管理員負(fù)責(zé)在這些屬性與真實(shí)的用戶(hù)信息數(shù)據(jù)庫(kù)(通常是LDAP服務(wù)器)之間建
立映射關(guān)系。
我們將在本文的第二部分深入討論這些特點(diǎn)-請(qǐng)求處理、用戶(hù)信息和portlet模式。
開(kāi)發(fā)"Hello World" Portlet 現(xiàn)在我們就來(lái)開(kāi)發(fā)一個(gè)簡(jiǎn)單的HelloWorld portlet。
1. 創(chuàng)建一個(gè)名為HelloWorld的web項(xiàng)目,它與通常的servlet項(xiàng)目類(lèi)似,有一個(gè)/WEB-INF/web.xml文件作為項(xiàng)目的部署描述符。
2. 在build path里加入portlet-api-1.0.jar文件,該jar文件是Pluto發(fā)行包的一部分。
3. 在Source文件夾中按如下內(nèi)容創(chuàng)建HelloWorld.java文件:
public class HelloWorld extends GenericPortlet{
protected void doView(RenderRequest request,
RenderResponse response) throws
PortletException, IOException {
response.setContentType("text/html");
response.getWriter().println("Hello Portlet");
}
}
每個(gè)portlet都要實(shí)現(xiàn)Portlet接口,該接口為portlet定義了生命周期方法。由于不想覆蓋所有這些方法,我們只對(duì)
GenericPortlet類(lèi)進(jìn)行擴(kuò)展,它是一個(gè)實(shí)現(xiàn)了Portlet接口的適配器類(lèi)。GenericPortlet類(lèi)提供了所有生命周期方法的默認(rèn)實(shí)
現(xiàn),所以我們只需實(shí)現(xiàn)我們所需要的方法。
我們?cè)?HelloWorld portlet里要做的只是顯示“Hello
Portlet”,所以我們將覆蓋GenericPortlet類(lèi)的doView()方法,該方法以PortletRequest 和
PortletResponse作為參數(shù)。在doView()方法中首先調(diào)用response.setContentType()以通知portlet容
器該portlet將要生成何種類(lèi)型的內(nèi)容-如果不這樣做就會(huì)導(dǎo)致IllegalStateException異常。一旦設(shè)置了內(nèi)容的類(lèi)型,就可以從
response對(duì)象中獲得PrintWriter并開(kāi)始寫(xiě)入。
4. 每個(gè)portlet應(yīng)用在/WEB-INF文件夾中都有一個(gè)portlet.xml文件,它是portlet應(yīng)用的部署描述符。按以下內(nèi)容創(chuàng)建portlet.xml文件:
<portlet>
<description>HelloWorldDescription
</description>
<portlet-name>HelloWorld
</portlet-name>
<display-name>Hello World
</display-name>
<portlet-class>com.test.HelloWorld
</portlet-class>
<expiration-cache>-1
</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW
</portlet-mode>
</supports>
<supported-locale>en
</supported-locale>
<portlet-info>
<title>Hello World</title>
<short-title>Hello World
</short-title>
<keywords>Hello,pluto</keywords>
</portlet-info>
</portlet>
<portlet-name>元素聲明了portlet的名字,<portlet-class>元素指定了portlet的全
限定類(lèi)名,<expiration-cache>元素以秒為單位指定了內(nèi)容超期的時(shí)間。這里面有一點(diǎn)需要注意:你在portlet上的某些動(dòng)
作可能會(huì)導(dǎo)致內(nèi)容刷新,這與緩存時(shí)間無(wú)關(guān)。
<supports>元素指定對(duì)于給定的<mime-type>有哪些模
式可供支持。在示例中我們假定HelloWorld只能生成text/html類(lèi)型的內(nèi)容,且只有view模式可支持該內(nèi)容類(lèi)型。如果要增加對(duì)其它內(nèi)容類(lèi)
型的支持,需要添加新的<support>元素并指定支持該MIME類(lèi)型的模式有哪些。通常portlet對(duì)于text/html類(lèi)型有
VIEW、EDIT和HELP模式可供支持,而對(duì)于WML MIME類(lèi)型則只有VIEW模式。
還可以用<supported-
locale>元素來(lái)指定portlet支持哪些本地化。<title>元素用來(lái)指定portlet的標(biāo)題。如果要對(duì)標(biāo)題做國(guó)際化處
理,可以用元素<resource-bundle>指定資源(比例properties文件)的文件名。在這種情況下,容器將根據(jù)用戶(hù)所在的
地區(qū)從適當(dāng)?shù)膒roperties文件中選擇標(biāo)題。
5. 每個(gè)portlet應(yīng)用都是一個(gè)web應(yīng)用,因此除了portlet.xml文件之外還需要有web.xml文件。
<web-app>
<display-name>Hello World Portlet
</display-name>
<welcome-file-list
<welcome-file>index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
6. 接下來(lái)將這些文件進(jìn)行編譯并打包為war文件。你可以自己完成這些工作,或者下載帶有build.xml 的示例代碼(參見(jiàn)“資源”部分)來(lái)創(chuàng)建war文件。
在Pluto上部署HelloWorld Portlet
Pluto尚處于開(kāi)發(fā)階段的早期,因此還沒(méi)有一套易于使用的管理工具。為了能使用Pluto服務(wù)器,需要將編譯和源代碼兩個(gè)版本都下載。需要注意的是以
下說(shuō)明是針對(duì)Windows平臺(tái)的,Unix用戶(hù)通過(guò)修改斜杠符號(hào)和執(zhí)行sh shell腳本(不是bat批命令文件)會(huì)得到類(lèi)似的結(jié)果。
1. 創(chuàng)建一個(gè)文件夾,比如C:\PlutoInstallation。
2. 從Pluto的網(wǎng)站下載pluto-1.0.1-rc1.zip和pluto-src-1.0.1-rc1.zip。
3. 將pluto-1.0.1-rc1.zip解壓到C:\PlutoInstallation.文件夾,它應(yīng)被解壓到C:\PlutoInstallation\pluto-1.0.1-rc1文件夾下。
4. 執(zhí)行C:\PlutoInstallation\pluto-1.0.1-rc1\bin\startup.bat啟動(dòng)Pluto,現(xiàn)在可以通過(guò)地址http://localhost:8080/pluto/portal訪問(wèn)Pluto服務(wù)器。
5. 將pluto-src-1.0.1-rc1.zip解壓到C:\PlutoInstallation\PlutoSrc文件夾。
6.
進(jìn)入C:\PlutoInstallation\PlutoSrc文件夾,執(zhí)行maven
distribute:all.,編譯并下載運(yùn)行常規(guī)管理任務(wù)所必需的相關(guān)資源文件。現(xiàn)在可以將HelloWorldPortlet.war作為
portlet進(jìn)行安裝了。
7. 首先將HelloWorldPortlet.war文件拷貝到C:\PlutoInstallation\portlets目錄,如果沒(méi)這個(gè)目錄就創(chuàng)建它。
8. 將C:\PlutoInstallation\plutosrc\build.properties.sample更名為build.properties。
9. 編輯build.properties,將maven.tomcat.home指向Pluto編譯版的安裝位置,在本例中應(yīng)改為maven.tomcat.home=C:/PlutoInstallation/pluto-1.0.1-rc1。
10.
為了安裝portlet,進(jìn)入C:\plutoInstallation\plutosrc\deploy文件夾,執(zhí)行maven deploy
-Ddeploy=c:\PlutoInstallation\portlets\HelloWorldPortlet.war,應(yīng)能看到“build
successful”信息。
11. 在C:\PlutoInstallation\pluto-1.0.1-rc1\webapps文件夾下,應(yīng)該有一個(gè)HelloWorldPortlet文件夾。
12. 現(xiàn)在進(jìn)入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\HelloWorld\WEB-INF\ folder文件夾,打開(kāi)portlet的web.xml文件,你會(huì)發(fā)現(xiàn)里面自動(dòng)多了幾行,如下所示:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<display-name>HelloWorld Wrapper</display-name>
<description>Automated generated
Portlet Wrapper</description>
<servlet-class>org.apache.pluto.core.PortletServlet
</servlet-class>
<init-param>
<param-name>portlet-class</param-name>
<param-value>com.test.HelloWorld
</param-value>
</init-param>
<init-param>
<param-name>portlet-guid</param-name>
<param-value>HelloPluto.HelloWorld
</param-value>
</init-param>
</servlet>
13.
接下來(lái)我們將該portlet加到頁(yè)面里。進(jìn)入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto
\WEB-INF\data文件夾,可以看到有兩個(gè)XML文件:pageregistry.xml和
portletentityregistry.xml。
14. portletentityregistry.xml包含了portlet的定義,在該文件中加入以下幾行:
<application id="5">
<definition-id>HelloWorld</definition-id>
<portlet id="1">
<definition-id>HelloWorld.HelloWorld</definition-id>
</portlet>
</application>
應(yīng)用的<definition-id>應(yīng)為web應(yīng)用所在文件夾的名字,portlet的<definition-id>應(yīng)與web.xml中生成的portlet-guid相一致。
15. pageregistry.xml定義了頁(yè)面中包含了哪些portlets,對(duì)該文件做如下改動(dòng):
<fragment name="p2" type="portlet">
<property name="portlet" value="5.1"/>
</fragment>
16. 執(zhí)行shutdown命令和startup命令重啟Pluto服務(wù)器,返回到地址http://localhost:8080/pluto/portal并點(diǎn)擊“Test Link”-此時(shí)頁(yè)面中將出現(xiàn)我們的
HelloWorld portlet。圖3的右側(cè)顯示了HelloWorld portlet看上去的樣子。

圖3 portlet的屏幕截圖
如何創(chuàng)建Portal頁(yè)面 圖4顯示了portal容器如何將分離的portlets組裝為頁(yè)面。

圖4 創(chuàng)建Portal頁(yè)面
大部分的portal服務(wù)器基本上都是部署于應(yīng)用服務(wù)器上的web應(yīng)用,通過(guò)servlet來(lái)處理訪問(wèn)portal服務(wù)器的請(qǐng)求。查看一下Pluto的
安裝目錄就會(huì)發(fā)現(xiàn)Pluto不過(guò)是一個(gè)部署于Tomcat服務(wù)器上的一個(gè)普通web應(yīng)用,再看看C:\PlutoInstallation\pluto-
1.0.1-rc1\webapps\pluto\WEB-INF\web.xml會(huì)發(fā)現(xiàn)所有發(fā)往Pluto服務(wù)器的請(qǐng)求都被映射到
org.apache.pluto.portalImpl.Servlet上。
在本文開(kāi)始部分“Portal頁(yè)面的元素”中,我們提到portal頁(yè)面由兩部分組成。一部分是由頁(yè)面中的portlets生成的內(nèi)容,另一部分是由portal服務(wù)器生成的內(nèi)容。
在Pluto里,只要用戶(hù)發(fā)出請(qǐng)求,就會(huì)由servlet進(jìn)行控制,根據(jù)用戶(hù)所請(qǐng)求的頁(yè)面來(lái)確定需要顯示的portlets的列表。一旦生成了列表,servlet就將控制轉(zhuǎn)給這些portlets線程并收集由它們生成的內(nèi)容。
對(duì)于由portal服務(wù)器生成的內(nèi)容(像portal網(wǎng)站的觀感及每個(gè)portlet的外觀和控制之類(lèi))則取決于C:\
PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\aggregation文件夾下的
JSP文件。RootFragment.jsp是主JSP文件,它決定了整體的觀感和對(duì)齊方式;它還包含了Heads以定義在生成的頁(yè)面中的<
HEAD>標(biāo)簽里的內(nèi)容。TabNavigation.jsp用來(lái)選擇在banner中該顯示什么(默認(rèn)情況下在banner顯示列表中也包擴(kuò)了
pluto.png圖片)。TabNavigation.jsp用來(lái)確定portal網(wǎng)站的導(dǎo)航方案。這意味著只需改動(dòng)該文件夾下少量的幾個(gè)JSP文件,
就能改變整個(gè)portal網(wǎng)站的觀感。
Pluto根據(jù)pageregistry.xml中的設(shè)置確定頁(yè)面中有多少行,并用
RowFragment.jsp去填充。ColumnFragment.jsp用來(lái)填充每個(gè)欄目。PortletFragmentHeader.jsp用
來(lái)填充每個(gè)portlet的頁(yè)頭,像標(biāo)題條及最大化和最小化控制。footer.jsp用來(lái)填充JSP的頁(yè)腳。如果去看一下portal頁(yè)面的HTML代
碼就會(huì)發(fā)現(xiàn)每個(gè)portlet窗口無(wú)非都是嵌入<TD>標(biāo)簽的內(nèi)容塊。
結(jié)束語(yǔ) 任何一種新技術(shù)要想獲得成功都應(yīng)具備以下條件:首先,它能提升現(xiàn)有技術(shù);其次,它能解決現(xiàn)有技術(shù)遇到的普遍問(wèn)題;再次,它能提供多于一個(gè)的抽象層(有人說(shuō),每抽象出一層,問(wèn)題就解決一半)。
由于portlet與現(xiàn)有的應(yīng)用服務(wù)器架構(gòu)兼容,這對(duì)Portlet
API來(lái)說(shuō)是一次發(fā)展servlet技術(shù)的好機(jī)會(huì)。你可以從portlet里調(diào)用EJB,或者用它啟動(dòng)和參與由應(yīng)用服務(wù)器控制的全局性事務(wù)。換句話說(shuō),在
以商業(yè)邏輯為核心的領(lǐng)域里,portlet完全可以做得和servlet一樣好。
Portlets提供了一個(gè)抽象層,現(xiàn)在你不必再擔(dān)
心客戶(hù)端使用了什么樣的HTTP方法,也不必自己編寫(xiě)程序去捕獲像點(diǎn)擊按鈕這樣的客戶(hù)端事件。最后但絕不是最次要的一點(diǎn)是,portlets以提供像單次
登錄、個(gè)性化等服務(wù)的方式解決了servlets不能解決的大部分問(wèn)題。
資源 ·
本文的示例代碼·JSR 168的首頁(yè):http://www.jcp.org/en/jsr/detail?id=168
·Pluto的首頁(yè):http://portals.apache.org/pluto/
·onjava.com:
onjava.com·Matrix-Java開(kāi)發(fā)者社區(qū):
http://www.matrix.org.cnSunil Patil從事J2EE技術(shù)工作已有5年,他感興趣的領(lǐng)域包括對(duì)象關(guān)系映射工具、UI框架以及portals。