天天看點

什麼是Porlet?

關鍵詞: Portlet Java

Portlets 

“Portlets是一種Web元件-就像servlets-是專為将合成頁面裡的内容聚集在一起而設計的。通常請求一個portal頁面會引發多個portlets被調用。每個portlet都會生成标記段,并與别的portlets生成的标記段組合在一起嵌入到portal頁面的标記内。”(摘自Portlet規範,JSR 168)

本文探讨了以下内容:

1.        Portal頁面的元素 

2.        Portal是什麼?

3.        Portlets是什麼?

4.        開發“Hello World” Portlet

5.        在Pluto上部署HelloWorld Portlet

6.        如何建立Portal頁面

7.        結束語 

8.        資源

  Portlet規範将portlet定義為一種“基于Java技術的web元件,由處理請求和生成動态内容的portlet容器管理”。這段話聽起來是不是有些費解?本文将說明portlets是什麼以及能用它們做什麼。

圖1顯示了在通路一個portal伺服器時浏覽器中頁面的樣子。

圖1 典型的portal伺服器的頁面(點選檢視原圖)

  如果仔細檢視浏覽器裡的頁面,就會看到頁面是由不同的“視窗”組成的。一個視窗用于重新整理天氣,另一個用于新聞,還有一個用于重新整理股價,等等。這裡的每一個視窗都代表了一個portlets。如果看得再仔細些,還會發現每個視窗都有一個标題條和一些按鈕,包括最小化和最大化按鈕。

  在系統裡,這些視窗是互相獨立開發、各不同的應用。新聞portlet的開發者建立應用并打包成war格式的檔案,随後portal伺服器的管理者在伺服器上部署該war檔案并建立頁面,接下來每個使用者會選擇在他的頁面裡有哪些應用。例如,如果使用者對股價不感興趣而對體育感興趣,他可以用“體育”視窗替換“股價”視窗。

  Portlet技術需要學習許多新概念,本文不可能全都涵蓋,是以本文分為兩部分。在第一部分裡我們詳細說明portals和portlets,并開發一個簡單的“Hello World”portlet;在第二部分我們将探讨一些進階主題。

  我們将用Apache的Pluto伺服器(Portlet API 1.0規範的參考實作)來測試我們的示例portlets,我們還會花些時間探讨如何安裝和使用Pluto伺服器。

Portal頁面的元素

圖2顯示了Portal頁面的各種元素。

圖2 portal頁面的元素

  每個portlet頁面由一個或多個portlet視窗組成,每個portlet視窗又分為兩部分:一個是外觀,它決定了portlet視窗的标題條、控制和邊界的樣式;另一個是portlet段,它由portlet應用填充。

  Portal伺服器決定了portal頁面的整體觀感,像辨別、标題條顔色、控制圖示等。通過修改幾個JSP和css模闆檔案就可以改變portal的整個觀感。我們将在“如何建立portal頁面”部分對此做深入讨論。

Portal是什麼?

  在了解portlet之前有必要先了解portal。在Portlet規範裡是這樣講的:“portal是一種web應用,通常用來提供個性化、單次登入、聚集各個資訊源的内容,并作為資訊系統表現層的宿主。聚集是指将來自各個資訊源的内容內建到一個web頁面裡的活動”。

  Portal的功能可以分為三個主要方面:

1.        Portlet容器:Portlet容器與servlet容器非常類似,所有的portlet都部署在portlet容器裡,portlet容器控制portlet的生命周期并為其提供必要的資源和環境資訊。Portlet容器負責初始化和銷毀portlets,向portlets傳送使用者請求并合成響應。

2.        内容聚集:Portlet規範中規定portal的主要工作之一是聚集由各種portlet應用生成的内容,我們将在“如何建立Portal頁面”部分對此做進一步讨論。

3.        公共服務:portlet伺服器的一個強項是它所提供的一套公共服務。這些服務并不是portlet規範所要求的,但portal的商業實作版本提供了豐富的公共服務以有别于它們的競争者。在大部分實作中都有望找到的幾個公共服務有:

         o 單次登入:隻需登入portal伺服器一次就可以通路所有其它的應用,這意味着你無需再分别登入每一個應用。例如一旦我登入了我的intranet網站,我就能通路mail應用、IM消息應用和其它的intranet應用,不必再分别登入這些應用。

  Portal伺服器會為你配置設定一個通行證庫。你隻需要在mail應用裡設定一次使用者名和密碼,這些資訊将以加密的方式存儲在通行證庫中。在你已登入到intranet網站并要通路mail應用的時候,portal伺服器會從通行證庫中讀取你的通行證替你登入到mail伺服器上。你對其它應用的通路也将照此處理。

          o個性化:個性化服務的基本實作使使用者能從兩方面個性化她的頁面:第一,使用者可以根據她的自身喜好決定标題條的顔色和控制圖示。第二,使用者可以決定在她的頁面上有哪些portlets。例如,如果我是個體育迷,我可能會用一個能提供我鐘愛球隊最新資訊的portlet來取代股票和新聞portlets。

        一些在個性化服務方面領先的商業實作版本允許你建立為使用者顯示什麼樣的應用所依據的标準(如收入和興趣)。在這種情況下,可以設定一些像“對任何收入為X的使用者顯示饋贈商品的portlet”和“對任何收入為X的使用者顯示打折商品的portlet”這樣的商業規則。

        此外還有一些公共服務,比如機器翻譯,是由portal伺服器将portlet生成的内容翻譯為使用者要求的語言。大部分的商業portal伺服器都支援手持裝置通路并具有針對不同的浏覽終端生成不同内容的能力。

Portlets是什麼?

  與servlets類似,portlets是部署在容器内用來生成動态内容的web元件。從技術角度講portlet是一個實作了javax.portlet.Portlet接口的類,它被打包成war檔案格式部署到portlet容器裡。

  Portlets在以下方面與servlets相似:

1.        portlets由特定的容器管理。

2.        portlets生成動态内容。

3.        portlet的生命周期由容器管理。

4.        portlets通過請求/響應模式與web用戶端互動。

  Portlets在以下方面與servlets相異:

1.        portlets隻能生成标記段,而不是整個文檔。

2.        portlets沒有可供直接通路的URL位址。不過你還是能夠讓别人通過URL通路到portlet,你可以把包含該portlet的頁面的URL發給他。

3.        portlets不能随意地生成内容,這是因為portlet生成的内容最終要成為portal頁面的一部分。如果portal伺服器要求的是html/text類型,那麼所有的portlets都應生成html/text類型的内容。再比方說,如果portal伺服器要求的是WML類型,那麼所有的portlets都應生成WML類型的内容。

  portlets還提供了一些附加的功能:

1.        設定參數的持久化存儲:portlets提供了一個PortletPreferences對象用來儲存使用者的設定參數。這些參數被存入一個持久化資料庫,這樣伺服器重新開機後資料依然有效。開發者不必關心這些資料存儲的具體實作機制。

2.        請求處理:portlets提供了更為細粒度的請求處理。對于使用者在portlet上動作時向該portlet發出的請求(一種稱為活躍期的狀态),或者因使用者在其它portlet上動作而引發的重新整理頁面請求,Portal伺服器提供了兩種不同的回調方法來處理。

3.        Portlet模式:portlets用模式的概念來表示使用者在做什麼。在使用mail應用的時候,你可能會用它來讀信、寫信或檢查信件――這些都是mail應用的預定功能,Portlets通常以VIEW模式提供這些功能。但還有一些活動,像指定重新整理時間或(重新)設定使用者名和密碼,這些活動允許使用者定制應用的行為,是以它們用的是EDIT模式。Mail應用的幫助功能用的是HELP模式。

  如果仔細想想其實這裡面并沒有什麼新東西,它們反而大部分都是普通的業務需求。Portlet規範的作用在于它提供了一個抽象層,這才是它對所有與之相關的人-最終使用者、開發者和管理者-的價值所在。

  作為一個開發者,我會将所有與VIEW模式有關的業務邏輯放入doView()方法,将與應用配置有關的業務邏輯放入doEdit()方法,将與幫助有關的邏輯放入doHelp()方法

  這就簡化了管理者對portlet應用的通路控制管理,因為他隻需改變portlet的通路權限就能決定使用者能做什麼。例如,如果mail應用的一個使用者能夠在EDIT模式下設定使用者名和密碼,那麼就可以斷定他具有EDIT模式通路權限。

  不妨考慮這樣一種情形:我是一個intranet網站的管理者,我的公司買了一個能顯示新聞資訊的第三方portlet應用,該應用允許使用者指定跟蹤新聞更新的URL位址,我想借助它為使用者顯示公司的内部新聞。另一個需求是我不想讓使用者通過該應用來跟蹤任何其它的新聞資訊來源。作為管理者,我可以為所有的使用者指定一個用于内部新聞更新的URL位址,同時通過改變portlet應用的部署描述符來取消其它人修改該位址的權限。

  由于所有的portlet應用都具有相似的UI界面,是以采用portlets可使網站對最終使用者更具吸引力。如果她想閱讀任何一個應用的幫助資訊,她可以點選幫助按鈕;她也知道點選編輯按鈕能讓她進入應用的配置屏。标準化的使用者界面使你的portlet應用更引人。

4.        視窗狀态:視窗狀态決定了portal頁面上留給portlet生成内容的空間。如果點選最大化按鈕,portlet将占據整個螢幕,成為使用者唯一可用的portlet;而在最小化狀态,portlet隻顯示為标題條。作為開發者應當根據可用空間的大小來定做内容。

5.        使用者資訊:通常portlets向送出請求的使用者提供個性化的内容,為了能更加行之有效,portlets需要通路使用者的屬性資訊,如姓名、email、電話等。PortletAPI為此提供了使用者屬性的概念,開發者能夠用标準的方式通路這些屬性,并由管理者負責在這些屬性與真實的使用者資訊資料庫(通常是LDAP伺服器)之間建立映射關系。

  我們将在本文的第二部分深入讨論這些特點-請求處理、使用者資訊和portlet模式。

開發"Hello World" Portlet

  現在我們就來開發一個簡單的HelloWorld portlet。

1.        建立一個名為HelloWorld的web項目,它與通常的servlet項目類似,有一個/WEB-INF/web.xml檔案作為項目的部署描述符。

2.        在build path裡加入portlet-api-1.0.jar檔案,該jar檔案是Pluto發行包的一部分。

3.        在Source檔案夾中按如下内容建立HelloWorld.java檔案:

  每個portlet都要實作Portlet接口,該接口為portlet定義了生命周期方法。由于不想覆寫所有這些方法,我們隻對GenericPortlet類進行擴充,它是一個實作了Portlet接口的擴充卡類。GenericPortlet類提供了所有生命周期方法的預設實作,是以我們隻需實作我們所需要的方法。

  我們在 HelloWorld portlet裡要做的隻是顯示“HelloPortlet”,是以我們将覆寫GenericPortlet類的doView()方法,該方法以PortletRequest 和PortletResponse作為參數。在doView()方法中首先調用response.setContentType()以通知portlet容器該portlet将要生成何種類型的内容-如果不這樣做就會導緻IllegalStateException異常。一旦設定了内容的類型,就可以從response對象中獲得PrintWriter并開始寫入。

4.        每個portlet應用在/WEB-INF檔案夾中都有一個portlet.xml檔案,它是portlet應用的部署描述符。按以下内容建立portlet.xml檔案:

  <portlet-name>元素聲明了portlet的名字,<portlet-class>元素指定了portlet的全限定類名,<expiration-cache>元素以秒為機關指定了内容超期的時間。這裡面有一點需要注意:你在portlet上的某些動作可能會導緻内容重新整理,這與緩存時間無關。

  <supports>元素指定對于給定的<mime-type>有哪些模式可供支援。在示例中我們假定HelloWorld隻能生成text/html類型的内容,且隻有view模式可支援該内容類型。如果要增加對其它内容類型的支援,需要添加新的<support>元素并指定支援該MIME類型的模式有哪些。通常portlet對于text/html類型有VIEW、EDIT和HELP模式可供支援,而對于WML MIME類型則隻有VIEW模式。

  還可以用<supported-locale>元素來指定portlet支援哪些本地化。<title>元素用來指定portlet的标題。如果要對标題做國際化處理,可以用元素<resource-bundle>指定資源(比例properties檔案)的檔案名。在這種情況下,容器将根據使用者所在的地區從适當的properties檔案中選擇标題。

5.        每個portlet應用都是一個web應用,是以除了portlet.xml檔案之外還需要有web.xml檔案。

6.        接下來将這些檔案進行編譯并打包為war檔案。你可以自己完成這些工作,或者下載下傳帶有build.xml 的示例代碼(參見“資源”部分)來建立war檔案。

在Pluto上部署HelloWorld Portlet

  Pluto尚處于開發階段的早期,是以還沒有一套易于使用的管理工具。為了能使用Pluto伺服器,需要将編譯和源代碼兩個版本都下載下傳。需要注意的是以下說明是針對Windows平台的,Unix使用者通過修改斜杠符号和執行sh shell腳本(不是bat批指令檔案)會得到類似的結果。

1.        建立一個檔案夾,比如C:\PlutoInstallation。

2.        從Pluto的網站下載下傳pluto-1.0.1-rc1.zip和pluto-src-1.0.1-rc1.zip。

3.        将pluto-1.0.1-rc1.zip解壓到C:\PlutoInstallation.檔案夾,它應被解壓到C:\PlutoInstallation\pluto-1.0.1-rc1檔案夾下。

4.        執行C:\PlutoInstallation\pluto-1.0.1-rc1\bin\startup.bat啟動Pluto,現在可以通過位址http://localhost:8080/pluto/portal通路Pluto伺服器。

5.        将pluto-src-1.0.1-rc1.zip解壓到C:\PlutoInstallation\PlutoSrc檔案夾。

6.        進入C:\PlutoInstallation\PlutoSrc檔案夾,執行mavendistribute:all.,編譯并下載下傳運作正常管理任務所必需的相關資源檔案。現在可以将HelloWorldPortlet.war作為portlet進行安裝了。

7.        首先将HelloWorldPortlet.war檔案拷貝到C:\PlutoInstallation\portlets目錄,如果沒這個目錄就建立它。

8.        将C:\PlutoInstallation\plutosrc\build.properties.sample更名為build.properties。

9.        編輯build.properties,将maven.tomcat.home指向Pluto編譯版的安裝位置,在本例中應改為maven.tomcat.home=C:/PlutoInstallation/pluto-1.0.1-rc1。

10.        為了安裝portlet,進入C:\plutoInstallation\plutosrc\deploy檔案夾,執行maven deploy-Ddeploy=c:\PlutoInstallation\portlets\HelloWorldPortlet.war,應能看到“buildsuccessful”資訊。

11.        在C:\PlutoInstallation\pluto-1.0.1-rc1\webapps檔案夾下,應該有一個HelloWorldPortlet檔案夾。

12.        現在進入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\HelloWorld\WEB-INF\ folder檔案夾,打開portlet的web.xml檔案,你會發現裡面自動多了幾行,如下所示:

13.        接下來我們将該portlet加到頁面裡。進入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\data檔案夾,可以看到有兩個XML檔案:pageregistry.xml和portletentityregistry.xml。

14.        portletentityregistry.xml包含了portlet的定義,在該檔案中加入以下幾行:

  應用的<definition-id>應為web應用所在檔案夾的名字,portlet的<definition-id>應與web.xml中生成的portlet-guid相一緻。

15.        pageregistry.xml定義了頁面中包含了哪些portlets,對該檔案做如下改動:

16.        執行shutdown指令和startup指令重新開機Pluto伺服器,傳回到位址http://localhost:8080/pluto/portal并點選“Test Link”-此時頁面中将出現我們的

HelloWorld portlet。

圖3的右側顯示了HelloWorld portlet看上去的樣子。

圖3 portlet的螢幕截圖

如何建立Portal頁面 

圖4顯示了portal容器如何将分離的portlets組裝為頁面。

圖4 建立Portal頁面

  大部分的portal伺服器基本上都是部署于應用伺服器上的web應用,通過servlet來處理通路portal伺服器的請求。檢視一下Pluto的安裝目錄就會發現Pluto不過是一個部署于Tomcat伺服器上的一個普通web應用,再看看C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\web.xml會發現所有發往Pluto伺服器的請求都被映射到org.apache.pluto.portalImpl.Servlet上。

  在本文開始部分“Portal頁面的元素”中,我們提到portal頁面由兩部分組成。一部分是由頁面中的portlets生成的内容,另一部分是由portal伺服器生成的内容。

  在Pluto裡,隻要使用者送出請求,就會由servlet進行控制,根據使用者所請求的頁面來确定需要顯示的portlets的清單。一旦生成了清單,servlet就将控制轉給這些portlets線程并收集由它們生成的内容。

  對于由portal伺服器生成的内容(像portal網站的觀感及每個portlet的外觀和控制之類)則取決于C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\aggregation檔案夾下的JSP檔案。RootFragment.jsp是主JSP檔案,它決定了整體的觀感和對齊方式;它還包含了Heads以定義在生成的頁面中的<HEAD>标簽裡的内容。TabNavigation.jsp用來選擇在banner中該顯示什麼(預設情況下在banner顯示清單中也包擴了pluto.png圖檔)。TabNavigation.jsp用來确定portal網站的導航方案。這意味着隻需改動該檔案夾下少量的幾個JSP檔案,就能改變整個portal網站的觀感。

  Pluto根據pageregistry.xml中的設定确定頁面中有多少行,并用RowFragment.jsp去填充。ColumnFragment.jsp用來填充每個欄目。PortletFragmentHeader.jsp用來填充每個portlet的頁頭,像标題條及最大化和最小化控制。footer.jsp用來填充JSP的頁腳。如果去看一下portal頁面的HTML代碼就會發現每個portlet視窗無非都是嵌入<TD>标簽的内容塊。

結束語

  任何一種新技術要想獲得成功都應具備以下條件:首先,它能提升現有技術;其次,它能解決現有技術遇到的普遍問題;再次,它能提供多于一個的抽象層(有人說,每抽象出一層,問題就解決一半)。

  由于portlet與現有的應用伺服器架構相容,這對PortletAPI來說是一次發展servlet技術的好機會。你可以從portlet裡調用EJB,或者用它啟動和參與由應用伺服器控制的全局性事務。換句話說,在以商業邏輯為核心的領域裡,portlet完全可以做得和servlet一樣好。

  Portlets提供了一個抽象層,現在你不必再擔心用戶端使用了什麼樣的HTTP方法,也不必自己編寫程式去捕獲像點選按鈕這樣的用戶端事件。最後但絕不是最次要的一點是,portlets以提供像單次登入、個性化等服務的方式解決了servlets不能解決的大部分問題。

資源 

·JSR 168的首頁:http://www.jcp.org/en/jsr/detail?id=168

·Pluto的首頁:http://portals.apache.org/pluto/ 

Sunil Patil從事J2EE技術工作已有5年,他感興趣的領域包括對象關系映射工具、UI架構以及portals。 

本文轉自kenty部落格園部落格,原文連結http://www.cnblogs.com/kentyshang/archive/2008/02/03/1063913.html如需轉載請自行聯系原作者

kenty