歡迎您光臨本站 註冊首頁

使用JSF、Ajax和Seam開發Portlets(3/3)

←手機掃碼閱讀     火星人 @ 2014-03-10 , reply:0

在這個系列文章的第一篇和第二篇中,我解釋了什麼是portlet bridge?以及如何在一個基本的JSF和基於RichFaces(Ajax)的portlet中安裝和使用它,和當前能支持運行JBoss Portlet Bridge的portal伺服器的主要區別.最后這篇文章將集中講述Seam portlet的開發,和最新發布的JBoss Portlet Bridge Beta 4版本的所有特性和優勢.對於不太熟悉portlets的讀者來說,仔細閱讀前面兩篇文章會有助於更好的理解本文.

現在讓我們先從Seam portlet的開發入手.

安裝Seam Portlet

開發工具:

要仿照本文示例進行開發,就需要下載最新版本的Maven(我用的是2.0.9版本).

安裝Maven 2.0.9 在機器上設置Maven binaries的path環境變數

創建項目:

不同的Maven原型(archetype)對應可以產生不同種類的bridge.直接從命令行運行如下代碼,可創建你的Seam portlet項目:

mvn archetype:generate
-DarchetypeGroupId=org.jboss.portletbridge.archetypes
-DarchetypeArtifactId=seam-basic -DarchetypeVersion=1.0.0.B4
-DgroupId=org.my.project -DartifactId=seamproject
-DarchetypeRepository=http://repository.jboss.org/maven2/ -Dversion=1.0.0.B4

該特定原型是模塊化的,這意味著通過其產生的項目將由幾個子項目構成.這樣做的好處是源碼、資源和配置之間的界限更加清晰,維護也更方便.上述命令將產生三個目錄,其中,『web』目錄中包含標記文件、圖片和WEB-INF xml配置文件;『ejb』目錄中包含所有Seam EJB3源碼,以及任何跟持久化和ejb部署相關的xml配置文件信息;最后是『ear』目錄,它主要用來集合項目信息構建ear文件.

如果你是用上面提到的原型(archetype)命令創建的項目,那麼現在你就會有一個『seamproject』目錄.現在到該目錄下並運行如下命令:mvn install

這個命令將會幫助你下載本地Maven庫中缺少的任何組件,並編譯和構建ear文件.

運行和部署portlet:

既然你已經有一個可部署的ear文件,那麼再利用下面的命令就可以輕鬆的將portlet部署到最新版本的JBoss Portal上(已綁定到JBoss應用伺服器)了.如果你已經自己下載或創建了本地安裝包,就可在bridge文檔中找到使用自定義配置的說明了.

現在轉到{seamproject}/ear目錄下運行如下命令:

mvn cargo:start -Premote-portal-Dportal-2.7.0.B1

該命令將花上一段時間(視你的網路情況而定)來下載最新版本的JBoss Application Server和JBoss Portal(軟體均位於SourceForge.net網站上).在繼續下一步驟之前你應該能看到與上文畫面相似的日誌記錄.*注意:你也許還會看到日誌記錄中不斷滾屏的WSRP信息,不用擔心,這同樣是證明你已準備就緒的標誌.

現在來部署你的Seam項目ear文件.新打開一個終端窗口,轉到目錄{seamproject}/ear下,運行如下命令:

mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

當你在伺服器日誌中看到ear文件已部署成功時,訪問鏈接http://localhost:8080/portal/portal/default/seamproject,會看到如下頁面:

現在我們已經準備好一個要開發Seam portlet了.當然,應用程序到底怎麼寫是由開發人員來決定的事情.但是這會幫你擺脫那些瑣碎的配置問題,輕鬆的開始工作.

配置

將JSF portlet轉換為一個典型的Seam應用,只需要少量的配置工作即可完成.下面的配置文件代碼省略了前面文章(第一部分和第二部分)已經提到過的配置信息.如果想了解詳細內容,請參照bridge文檔的配置部分.

web.xml

------------------

下面的這段配置通常是任何Seam應用中都會有的內容,並且不會portlet環境而有所不同:

<listener>
<listener-class>
org.jboss.seam.servlet.SeamListener
</listener-class>
</listener>
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>
org.jboss.seam.servlet.SeamResourceServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dspatcher>
</filter-mapping>

配置ExceptionHandler上下文參數,可允許bridge應用現成的異常處理器去解決基於Seam的異常.如果願意的話,你也完全可以應用自己的實現:

<context-param>
<param-name>org.jboss.portletbridge.ExceptionHandler</param-name>
<param-value>
org.jboss.portletbridge.SeamExceptionHandlerImpl
</param-value>
</context-param>

Bridgelet是針對portlet bridge擴展(extension)的名稱.portlet bridge社區一直在積極的開發一些擴展以增強或集中JBoss Portal、Seam和Richfaces三者的特性,例如,PortalIdentity(SSO)seam組件可允許你把jar文件放在你的 classpath上,這樣你立刻就會有一個可用於Seam和Portal之間的SSO了.你也可以在Maven pom中將這個擴展配置成一個依賴(象下面將看到的那樣).

如果你對Bridgelet有什麼建議,或者有意參與JBoss Portlet Bridge的開發工作,那麼我們期待你積極加入我們的論壇並提交Jira tasks.

Seam應用和JBoss Portal之間的單點登錄問題

開發人員可以把Seam Booking Demo用做一個開發和測試的portlet參考程序.如果想了解和實踐SSO Bridgelet,你可以從此地址http://anonsvn.jboss.org/repos/portletbridge/tags/1.0.0.B4/examples/seam/booking/下載源代碼,然後運行與此篇文章上面剛剛講過的完全相同的maven部署命令(或者是下面將要講到的簡短版本)來部署和運行該程序.

簡短版本是:轉到{SeamBooking}根目錄下,運行如下命令:mvn install

然後再轉到{SeamBooking}/ear目錄下,運行:mvn cargo:start -Premote-portal-Dportal-2.7.0.B1

現在再來部署你的Seam項目ear文件.新打開一個終端窗口,在{SeamBooking}/ear目錄下運行如下命令:

mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

一旦你部署完成並運行demo后,就可以訪問鏈接http://localhost:8080/portal/portal/default/SeamBooking繼續下面的步驟了.點擊「註冊新用戶(Register New User)",新建一個用戶並用其登錄系統:

登錄之後你將會看到酒店搜索頁面,還有與當前登錄角色對應的所有功能.但是,如果你看向屏幕右上角,你會發現登錄到Seam應用和你的JBoss Portal用戶/管理員賬戶一點關係都沒有:

這就是我們需要SSO Bridgelet的理由,它允許通過Seam身份認證模塊來驗證JBoss Portal用戶名.現在讓我們來嘗試一下:令伺服器依然保持運行狀態,在進行部署的那個終端窗口中,返回到上一級目錄,也就是{SeamBooking}/根目錄下運行如下命令:mvn install -Psso

接下來再轉到{SeamBooking}/ear目錄下運行如下命令:mvn cargo:deploy-Premote-portal -Dportal-2.7.0.B1

通過上述命令我們將SSO jar包嵌入進了應用,並重新部署了一次ear文件.

現在,讓我們回到http://localhost:8080/portal/portal/default/SeamBooking上的portlet.這次我們登錄到portal而不是Seam應用.點擊頁面右上方的portal login進行登錄,用戶名和密碼都是『admin』.

如果這是一個現實中的應用,我們會對UI做一點調整,把Seam應用的登錄表單隱藏起來.同時SSO的存在,我們可以調整網站其它基於角色的內容.但是,正如我前面所說,這是從最原始狀態的Seam booking demo出發做最小改動能達到的效果,只是一個參考.

登錄到JBoss Portal后,在你的Seam和Portal UI上你將會看到如下內容:

在解決了Portal和你的Seam應用之間的身份認證問題后,應用的創建就變得容易些了.如果你的Seam portlet是基於Maven創建的,那麼還需要你做的就只有在pom.xml文件中添加如下代碼了:

<dependency>
<groupId>org.jboss.portletbridge.extensions.seam</groupId>
<artifactId>PortalIdentity</artifactId>
<version>1.0.0.B4</version>
</dependency>

或者你也可以把PoralIdentity.jar文件放到應用程序WEB-INF/lib目錄下就行了,不再需要做別的配置了.

JBoss Portlet Bridge Beta4概述

既然這是本系列文章的最后一篇,那麼在最后一部分我將介紹9月11日剛剛發布的JBoss Portlet Bridge Beta 4版本的新特性.

支持PortletMode變化

一個PortletMode代表了應用中一個不同的展現路徑(render path),有三種標準的模式:view、edit和help.bridge的ExternalContext.encodeActionURL 可以辨認查詢字元串參數javax.portlet.faces.PortletMode,並用這個參數值在底層portlet actionURL或響應上設置portlet模式. 一旦處理完就要把這個參數從查詢字元串中去掉.下述導航規則將會在portlet的edit模式下呈現viewId為edit.jspx的頁面:

<navigation-rule>
<from-view-id>/register.jspx</from-view-id>
<navigation-case>
<from-outcome>edit</from-outcome>
<to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit</to-view-id>
</navigation-case>
</navigation-rule>

導航至一個模式的最終viewId

預設地,一個模式的改變將從模式的默認視圖(不帶狀態)開始.對於一個普通的portlet模式,在其返回到進入另一模式之前的那個模式時(例如:view->edit->view),它將會跳轉到這個模式(離開之前)的最終視圖(和狀態).bridge能夠對必要信息進行清楚的編碼,以便有需要返回到前一個模式時,它可以定位到適當的視圖,並恢復到應有的狀態.開發人員可以使用由bridge維護的session屬性,以便從一個模式導航回其前一個模式的最終位置和狀態.同樣,開發人員需要描述一個動態導航:「從視圖X返回到模式Y的最終視圖」.這可以用由EL表達式簡單地表示如下:

<navigation-rule>
<from-view-id>/edit.jspx*</from-view-id>
<navigation-case>
<from-outcome>view</from-outcome>
<to-view-id>#{sessionScope['javax.portlet.faces.viewIdHistory.view']}</to-view-id>
</navigation-case>
</navigation-rule>

Portlet開發人員需要注意的問題

根據bridge實現,當用到這些session範圍的屬性值、或者任何可能包含查詢字元串參數的viewIds時,最好在驗證規則目標(rule target)時使用通配符語法.例如,上面的<to-view-id>表達式返回的是一個表單的viewId(/viewId?javax.portlet.faces.PortletMode=view&……).其不含通配符,因此當該新視圖發生頁面跳轉時,導航規則就無法解析了,它找不到任何可與之完全匹配的對象.

而上面的edit.jspx <from-view-id>包含了通配符,導航規則就可用查詢串(<to-view-id> /edit.jspx?javax.portlet.faces.PortletMode=edit </to-view-id>)來和它匹配.強烈建議開發人員都使用這種通配符以確保程序可以在各種bridge實現中正常執行.

處理Portlet中的Ajax錯誤

默認的,錯誤是由處理Ajax請求的標準servlet頁面來解決.要在portlet內部處理錯誤,就要用到下面的JavaScript代碼:

<script type="text/javascript">
A4J.AJAX.onError = function(req,status,message){
window.alert("Custom onError handler " message);
}

A4J.AJAX.onExpired = function(loc,expiredMsg){
if(window.confirm("Custom onExpired handler " expiredMsg " for a location: " loc)){
return loc;
} else {
return false;
}
}
</script>

結論

正如前面所說,portlet bridge社區從項目早期測試階段就已經開始發布補丁和其它形式的幫助來促進其發展.雖然項目的核心是JSR-301規範,然而整合Seam、 Richfaces、Portal和Bridgelets以及其它輔助性的加強功能是具有無限潛能和意義的.已經有些開發人員為項目的發展貢獻了他們的力量,在此我們對所有這些提供過補丁、增強構件以及在論壇上積極回答問題的人們表示衷心的感謝.

最后,這是一個基於社區的項目,提供幫助和反饋的開發人員越多,我們的新產品發布的越快,其功能也就更強,代碼也更完善.預計GA版本會在09年初發布.


[火星人 ] 使用JSF、Ajax和Seam開發Portlets(3/3)已經有515次圍觀

http://coctec.com/docs/java/show-post-61978.html