国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Apache 門戶項(xiàng)目組介紹
級(jí)別: 初級(jí)
廖 健, 首席實(shí)施顧問
2006 年 11 月 02 日
本文將快速瀏覽 Apache 門戶項(xiàng)目組的所有項(xiàng)目,并著重介紹門戶項(xiàng)目組中的核心項(xiàng)目-Jetspeed-2。
JEE作為建立在Java平臺(tái)上的企業(yè)級(jí)應(yīng)用解決方案,經(jīng)過這些年不斷發(fā)展,已經(jīng)成為企業(yè)級(jí)開發(fā)的工業(yè)標(biāo)準(zhǔn)和首選平臺(tái)。眾多廠商如IBM,BEA和Oracle等都圍繞該規(guī)范推出了相應(yīng)的,功能強(qiáng)大的產(chǎn)品。JEE規(guī)范組中最受業(yè)界認(rèn)同和取得最大成功的就是JEE Web層面規(guī)范,發(fā)展到今天,已經(jīng)步入門戶(Portal)的時(shí)代。
門戶,簡言之就是提供包括內(nèi)容聚合、單點(diǎn)登陸、個(gè)性化定制和安全管理等服務(wù)的基礎(chǔ)Web平臺(tái)。眾多JEE產(chǎn)品提供商基于JEE Web層技術(shù)推出了自己的Portal產(chǎn)品,著名的產(chǎn)品有IBM WebSphere Portal Server,BEA Weblogic Portal Server等。一直處于技術(shù)前沿的著名開源社區(qū)Apache,經(jīng)過這幾年的技術(shù)積累也形成了自己的門戶項(xiàng)目組。該項(xiàng)目組目前已經(jīng)初具規(guī)模,并且擁有了一定的用戶群體,經(jīng)受了一定的市場考驗(yàn)。
本文主要面向有一定JEE編程經(jīng)驗(yàn)的Java開發(fā)者和試圖構(gòu)建自己的門戶軟件產(chǎn)品的產(chǎn)品經(jīng)理,因?yàn)榛陂_源項(xiàng)目構(gòu)建企業(yè)級(jí)的商用產(chǎn)品,已經(jīng)在國外取得了許多成功案例。
名詞 解釋
Portal 門戶,提供包括內(nèi)容聚合、單點(diǎn)登陸、個(gè)性化定制和安全管理等服務(wù)的基礎(chǔ)Web平臺(tái)。
Portlet Portlet是基于web的Java組件。它由Portlet容器管理,能夠處理請(qǐng)求,產(chǎn)生動(dòng)態(tài)內(nèi)容。Portlet被Portal用作為可插拔的用戶接口組件,為信息系統(tǒng)提供展現(xiàn)。由Portlet動(dòng)態(tài)產(chǎn)生的內(nèi)容也被叫做fragment。fragment是遵循某種規(guī)則的標(biāo)記(例如:HTML, XHTML,WML),可與其他的fragment一起建立一個(gè)完整的文檔。一般一個(gè)Portlet產(chǎn)生的內(nèi)容和其他的Portlet產(chǎn)生的內(nèi)容聚集在一起形成Portal網(wǎng)頁。
Portlet Container Portlet在Portlet容器中運(yùn)行,Portlet容器為Portlet提供必需的運(yùn)行環(huán)境。Portlet容器包含Portlet(組件)并且管理它們的生命周期,它也為Portlet的參數(shù)設(shè)置提供持久化的存儲(chǔ)。Portlet 容器不是一個(gè)類似于 servlet 容器的獨(dú)立容器。它是在 servlet 容器上通過擴(kuò)展方式實(shí)現(xiàn)的,并重用 servlet容器提供的功能。從Portal的角度來看,Portlet Container是Portal平臺(tái)所提供的眾多服務(wù)之一。
JSR168,JSR286 由于越來越多的公司開發(fā)了各自的Portal組件和基于其的Portal產(chǎn)品(如Bea, IBM, Oracle, Sun, Sybase, Novell, SAP, Jetspeed, Vignette 等.這種互不兼容的接口實(shí)現(xiàn)不斷帶給程序提供商各種問題和麻煩, 為了解決這種問題, JCP發(fā)布了JSR168 (Java Specification Request), Portlet Specification, 用以提供不同Portal和Portlets之間的互用性。JSR 286是168規(guī)范的延伸,是目前最新標(biāo)準(zhǔn)規(guī)范,目前仍處在draft狀態(tài)。
SSO Single Sign-On,即單點(diǎn)登陸。當(dāng)一個(gè)大系統(tǒng)中存在多個(gè)子系統(tǒng)時(shí),用戶只需要正確登陸其中任何一個(gè)子系統(tǒng),就可以在各個(gè)子系統(tǒng)中來回自由切換和使用授予該用戶權(quán)限的各種資源。一般可以分為兩種類型:Web應(yīng)用之間的單點(diǎn)登陸和門戶Web應(yīng)用和它所連接的后臺(tái)系統(tǒng)之間的單點(diǎn)登陸。SSO是任何一個(gè)門戶產(chǎn)品必須解決的問題,必須提供的服務(wù)。
WSRP WSRP是OASIS組織的一個(gè)規(guī)范,它定義了遠(yuǎn)程門戶網(wǎng)站的Web服務(wù)。通過Web Service將遠(yuǎn)程內(nèi)容抓取到本地,最后通過本地內(nèi)容聚合引擎展示出來。
在引言中已經(jīng)列舉了Apache門戶項(xiàng)目組的組成項(xiàng)目包括:Jetspeed-1/2,Bridges,Pluto,WSRP-4J和Graffito。由于Jetspeed-1和Jetspeed-2角色相同,下文中如果沒有特別指出,所有Jetspeed都是指Jetspeed-2。
上圖中粉紅色包圍部分為Apache門戶項(xiàng)目,其它由土黃色包圍部分為它們的依賴項(xiàng)目。通過上圖可以很清楚看到,全部項(xiàng)目都構(gòu)建在JEE Web Tier上,理論上只要支持Servlet 2.3或以上版本規(guī)范的Web容器,都可以作為Apache門戶項(xiàng)目的基礎(chǔ)平臺(tái),但Jetspeed官方其實(shí)僅僅聲明Tomcat是其唯一支持的Web容器。另一塊必要的依賴,是構(gòu)建在O/R mapping項(xiàng)目Apache OJB之上的數(shù)據(jù)倉庫,用于存放Portal系統(tǒng)信息和用戶個(gè)性化配置(Profile)。
Portals Bridges項(xiàng)目其本質(zhì)就是由一組類庫構(gòu)成的輕量級(jí)框架,通過該橋接器框架可以在門戶上支持眾多流行的Web框架,如上圖括號(hào)中所列舉。用戶通過它可以很容易的將已有的基于這些流行Web框架的Web應(yīng)用程序,通過少量的修改和配置,作為Portlet應(yīng)用程序發(fā)布單元發(fā)布到Portal上。這個(gè)項(xiàng)目不但在Jetspeed上取得的成功,還被眾多開源的,甚至商用的門戶實(shí)現(xiàn)所使用,如JBoss Portal,GridSphere Portal,Stringbeans PortalVignette Application Portal,Apache Cocoon PortalJetspeed Portal
Jetspeed項(xiàng)目是整個(gè)Apache Portal項(xiàng)目組的核心,它是一個(gè)功能完備的,易于擴(kuò)展的企業(yè)級(jí)Portal實(shí)現(xiàn),將在下面的文章中著重介紹它。
Pluto是Jetspeed默認(rèn)的本地Portlet Container實(shí)現(xiàn),它是一個(gè)完全符合JSR-168規(guī)范的Portlet容器實(shí)現(xiàn),其前身為IBM捐贈(zèng)的源代碼,因此我們至今還能夠在WebSphere Portal 5.1.1中看到它的身影。這里要注意本地的意思是指運(yùn)行在該P(yáng)ortlet容器里的Portlet應(yīng)用程序在物理上與Portal在同一個(gè)JVM進(jìn)程中。
WSRP-4j是WSRP規(guī)范的JAVA實(shí)現(xiàn),目前該項(xiàng)目還處在孵育狀態(tài),尚未吸引到足夠多的開發(fā)者的興趣。其實(shí),我個(gè)人認(rèn)為這是一個(gè)很有前途的技術(shù)發(fā)展方向,它可以提供類似Html IFrame這樣速成的內(nèi)容抓取能力。Jetspeed已經(jīng)為WSRP-4j預(yù)留了遠(yuǎn)程Portlet Container的配置選項(xiàng)。
Graffito是用于構(gòu)建內(nèi)容管理應(yīng)用程序的框架,從它自身的架構(gòu)設(shè)計(jì)上來看應(yīng)該是一個(gè)獨(dú)立平臺(tái),但事實(shí)上該項(xiàng)目復(fù)用了大量Jetspeed的模塊,并且其表現(xiàn)層為發(fā)布到Jetspeed上的幾個(gè)Portlet應(yīng)用程序,因此,我在上面的架構(gòu)圖中,將它放在了Jetspeed之上。該項(xiàng)目目前也處在孵育狀態(tài)下,由于其該項(xiàng)目目前不太活躍,那幾個(gè)Portlet應(yīng)用程序都有些小問題。
標(biāo)準(zhǔn)
完整兼容Java Portlet API標(biāo)準(zhǔn)1.0(JSR-168) 通過JSR-168規(guī)范兼容性測試 基于JAAS標(biāo)準(zhǔn)的認(rèn)證和授權(quán)服務(wù)(默認(rèn)支持?jǐn)?shù)據(jù)庫的實(shí)現(xiàn)) 基于LDAP的用戶認(rèn)證
體系架構(gòu)
基于Spring Framework的組件架構(gòu) 靈活可配置的請(qǐng)求通道(通過Spring Bean XML配置) Portlet應(yīng)用發(fā)布單元熱部署 Jetspeed AJAX XML API(基于著名的開源AJAX Framework -DOJO) 擴(kuò)展的Portlet頁面結(jié)構(gòu)語言(支持持久化到文件或數(shù)據(jù)庫)
門戶核心特性
聲明風(fēng)格的安全約束 基于角色的Portlet安全方面的API 門戶內(nèi)容管理和導(dǎo)航,包括頁面、菜單、文件夾和超鏈接 單線程或多線程的內(nèi)容聚合引擎(通過Spring Bean可以輕易切換) 高度可擴(kuò)展的Jetspeed 單點(diǎn)登陸服務(wù)框架 基于權(quán)限和規(guī)則的門戶頁面和資源定位配置 支持所有主流的數(shù)據(jù)庫,包括:Derby、MySQL、MS SQL、Postgres、Oracle、DB2、 Hypersonic 不依賴客戶端類型的capability engine (html, xhtml, wml,vml) 多語言支持(12國語言,包括簡體中文和繁體中文),而且完全可擴(kuò)展 完整的性能統(tǒng)計(jì)日志引擎 利用著名開源搜索引擎Lucene提供對(duì)所有門戶資源的全文本檢索和元數(shù)據(jù)搜索服務(wù) 用戶注冊(cè)服務(wù)和忘記密碼的郵件通知服務(wù) 豐富的登陸密碼配置策略
門戶管理
用戶,角色,用戶組,密碼和Profile管理 JSR 168協(xié)議規(guī)范定義的用戶屬性編輯器 門戶頁面管理 單點(diǎn)登陸服務(wù)管理 Portlet應(yīng)用程序管理 Profiler管理 門戶性能統(tǒng)計(jì)報(bào)告
對(duì)Web框架的支持和例子Portlets
通過Bridges項(xiàng)目支持幾乎所有的主流Web Framework與Jetspeed門戶的整合,包括:JSF(Sun的標(biāo)準(zhǔn)JSF實(shí)現(xiàn)和Apache MyFaces)、Apache Struts、PHP、Perl、Velocity 例子Portlet包括:RSS、IFrame(通過Jetspeed SSO API還可以支持SSO效果)、日歷、書簽。 支持Spring MVC
用戶個(gè)性化
門戶頁面管理 頁面用戶定制(包括增刪查改門戶頁面,頁面的風(fēng)格,Portlet框體風(fēng)格,Portlet的位置,Portlet的布局等等) 支持兩種門戶定制風(fēng)格,包括傳統(tǒng)的基于頁面刷新的風(fēng)格和基于AJAX技術(shù)的風(fēng)格
門戶設(shè)計(jì)
支持Portlet和Portal頁面皮膚的打包發(fā)布 基于CSS技術(shù)的可配置布局 支持Velocity模版引擎
門戶開發(fā)工具
支持Maven 1.x和Maven2.0.x,部分功能支持Ant腳本 支持通過Maven插件生成自定義門戶基礎(chǔ)框架 熱部署Portlet應(yīng)用發(fā)布單元和門戶資源 支持通過API調(diào)用的方式部署Portlet應(yīng)用發(fā)布單元 支持Eclipse3.2.x開發(fā)環(huán)境
應(yīng)用服務(wù)器
Apache Tomcat 5.0.x Apache Tomcat 5.5.x IBM WebSphere Application Server 5.1/6.0 JBoss Geronimo 1.0(非官方支持,詳見:JS2-444)
本節(jié)將從Jetspeed和Spring的關(guān)系,運(yùn)行時(shí)架構(gòu)以及Jetspeed service架構(gòu)這三方面詳細(xì)介紹Jetspeed的架構(gòu)體系。
Jetspeed和Spring
Jetspeed架構(gòu)體系最大特點(diǎn),也是其高度可訂制的根基就是,它選用著名開源POJO框架Spring作為其底層實(shí)現(xiàn)。在項(xiàng)目之初,Jetspeed的開發(fā)者們也面臨著Spring和PicoContainer的抉擇,但事實(shí)證明當(dāng)初的選擇是正確的,因?yàn)殡S著Spring不斷成長完善,Jetspeed的組件架構(gòu)也跟著收益良多。從另一個(gè)角度來看,Jetspeed也可以作為利用Spring構(gòu)建自己產(chǎn)品架構(gòu)的經(jīng)典范例,值得我們考察和學(xué)習(xí)。
下圖簡單描述了目前Jetspeed對(duì)Spring的依賴關(guān)系:
Beans BeanFactory and the ApplicationContext
Jetspeed主要使用了Spring最核心的IoC引擎BeanFactory和ApplicationContext,管理所有Jetspeed Components的生命周期和依賴關(guān)系,所有這些組件的Spring聲明全部定義在名為assembly的文件夾中的XML文件里。如果第三方開發(fā)者認(rèn)為默認(rèn)的Jetspeed組件不足以滿足要求,只要按照自己需求編寫Jetspeed Component的Interface的實(shí)現(xiàn)類,然后修改Spring Bean XML定義,就可以輕易替換掉默認(rèn)的實(shí)現(xiàn)。例如:
<beans default-lazy-init="false" default-dependency-check="none" default-autowire="no"> <!-- SEARCH COMPONENT --> <bean id="org.apache.jetspeed.search.SearchEngine" class="org.apache.jetspeed.search.lucene.SearchEngineImpl" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg index="0"> <value>${applicationRoot}/WEB-INF/search_index</value> </constructor-arg> <constructor-arg index="1"> <null /> </constructor-arg> <constructor-arg type="boolean"> <value>true</value> </constructor-arg> <constructor-arg> <ref bean="org.apache.jetspeed.search.HandlerFactory" /> </constructor-arg> </bean> </beans>
Jetspeed在實(shí)現(xiàn)過程中遵循著面向接口編程的最佳實(shí)踐,上圖中的Bean id為org.apache.jetspeed.search.SearchEngine,事實(shí)上這是一個(gè)定義在核心jetspeed-api組件中的接口,org.apache.jetspeed.search.lucene.SearchEngineImpl為該接口的實(shí)現(xiàn)類,這個(gè)類定義在components/search組件中,后面的內(nèi)容就是SearchEngineImpl的構(gòu)造函數(shù)的輸入?yún)?shù),注意最后一個(gè)參數(shù)org.apache.jetspeed.search.HandlerFactory也是一個(gè)Java Interface的接口。Spring在實(shí)例化SearchEngine的時(shí)候,會(huì)首先分析它的構(gòu)造函數(shù)參數(shù)是否已經(jīng)全部滿足條件(實(shí)例化),Spring會(huì)根據(jù)搜索bean id為org.apache.jetspeed.search.HandlerFactory的bean,如果已經(jīng)實(shí)例化就直接注入到SearchEngineImpl的構(gòu)造函數(shù)調(diào)用里;如果沒有就實(shí)例化這個(gè)bean之后,再注入。
Apache OJB O/R Mappers
由于Spring對(duì)Apache OJB提供良好的支持,因此Jetspeed中與數(shù)據(jù)庫相關(guān)的功能基本上都用過Spring的PersistenceBrokerDaoSupport實(shí)現(xiàn)。這些組件包括:Capablity、DatabasePageManager、PipeLine、Preferences、Profiler、Registry、Security、SSO等。O/R Mapping的信息定義在上面這些組件jar包中的JETSPEED-INF/ojb/%component name%_repository.xml文件中,其中%component name%需要用組建名稱替代。
Declarative transaction management
在Jetspeed中,你找不到一行有關(guān)于數(shù)據(jù)庫事務(wù)的代碼,這是因?yàn)樗捎昧薙pring的declarative transaction機(jī)制,下面一段XML定義了SSOProvider的事物管理:
<beans default-lazy-init="false" default-dependency-check="none" default-autowire="no"> <!-- SSO Implementation --> <bean id="PersistenceBrokerSSOProvider" class="org.apache.jetspeed.sso.impl.PersistenceBrokerSSOProvider" init-method="init" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg index="0"> <value>JETSPEED-INF/ojb/sso_repository.xml</value> </constructor-arg> </bean> <bean id="org.apache.jetspeed.sso.SSOProvider" parent="baseTransactionProxy" name="ssoProvider" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <property name="proxyInterfaces"> <value>org.apache.jetspeed.sso.SSOProvider</value> </property> <property name="target"> <ref bean="PersistenceBrokerSSOProvider" /> </property> <property name="transactionAttributes"> <props> <prop key="addSite*">PROPAGATION_REQUIRED</prop> <prop key="updateSite*">PROPAGATION_REQUIRED</prop> <prop key="removeSite">PROPAGATION_REQUIRED</prop> <prop key="addCredentialsForSite">PROPAGATION_REQUIRED</prop> <prop key="updateCredentialsForSite">PROPAGATION_REQUIRED</prop> <prop key="removeCredentialsForSite">PROPAGATION_REQUIRED</prop> <prop key="setRealmForSite">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_SUPPORTS</prop> </props> </property> </bean> </beans>
由上圖可知,通過Spring 的Declarative Transaction機(jī)制,Jetspeed很輕易實(shí)現(xiàn)了細(xì)顆粒度的事物管理,用戶可以很容易配置需要管理事務(wù)的方法,如"addSite*"、"updateSite*"和"removeSite"等等,其中"*"為通配符,詳細(xì)信息見此處
Spring MVC
由于Jetspeed對(duì)Spring的天生依賴,很自然Jetspeed也支持基于Spring MVC framework,詳見Jetspeed自帶的例子Portlet應(yīng)用程序。
Jetspeed 組件架構(gòu)啟動(dòng)過程
看了前面的介紹,你一定想知道Jetspeed是如何將基于Spring的組件架構(gòu)和標(biāo)準(zhǔn)JEE Web Application架構(gòu)融合在一起,本節(jié)將通過描述Jetspeed Web Application的啟動(dòng)過程來了解融合的細(xì)節(jié)。首先請(qǐng)看下圖:
請(qǐng)點(diǎn)擊這里查看Jetspeed Portal啟動(dòng)流程圖的大圖
由上圖可知,Jetspeed Portal從JEE角度來看其實(shí)就是一個(gè)標(biāo)準(zhǔn)的Web應(yīng)用程序,只不過在Servlet架構(gòu)上引入了Component Manager的概念,然后用Spring實(shí)現(xiàn)了ComponentManager接口。因此如果你不滿意Spring :,更換它也是有可能的。當(dāng)Servlet被容器停止時(shí),也會(huì)同時(shí)關(guān)閉SpringComponentManager。Servlet啟動(dòng)完畢后,所有通過Spring Bean XML定義POJO都被實(shí)例化了,除了那些指定了lazy init屬性為true的Bean。
Runtime架構(gòu)
JetspeedServlet
Jetspeed的運(yùn)行時(shí)大環(huán)境是符合Servlet 2.3或以上規(guī)范的JEE Web容器,因此大家可以通過觀察其web.xml了解或擴(kuò)展其功能。下面是Jetspeed.war的web.xml:
<web-app> <display-name>Jetspeed-2 Enterprise Portal</display-name> <!-- Log4JConfigurator context-listener parameters --> <context-param> <param-name>log4j.config.file</param-name> <param-value>/WEB-INF/conf/Log4j.properties</param-value> </context-param> <context-param> <param-name>log4j.config.webApplicationRoot.key</param-name> <param-value>applicationRoot</param-value> </context-param> <filter> <filter-name>AJAXFilter</filter-name> <filter-class>org.apache.jetspeed.ajax.AJAXFilter </filter-class> </filter> <filter-mapping> <filter-name>AJAXFilter</filter-name> <url-pattern>*.ajax</url-pattern> </filter-mapping> <listener> <listener-class>org.apache.jetspeed.webapp.logging. Log4JConfigurator</listener-class> </listener> <listener> <listener-class>org.apache.jetspeed.engine.JetspeedServlet </listener-class> </listener> <servlet> <servlet-name>jetspeed</servlet-name> <servlet-class>org.apache.jetspeed.engine.JetspeedServlet </servlet-class> <init-param> <param-name>properties</param-name> <param-value>/WEB-INF/conf/jetspeed.properties</param-value> </init-param> <init-param> <param-name>applicationRoot</param-name> <param-value>webContext</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> - <!-- Define Velocity template compiler --> <servlet> <servlet-name>velocity</servlet-name> <servlet-class>org.apache.jetspeed.velocity. JetspeedVelocityViewServlet</servlet-class> <init-param> <param-name>org.apache.velocity.toolbox</param-name> <param-value>/WEB-INF/toolbox.xml</param-value> </init-param> <init-param> <param-name>org.apache.velocity.properties</param-name> <param-value>/WEB-INF/velocity.properties</param-value> </init-param> <init-param> <param-name>org.apache.jetspeed.cache.size</param-name> <param-value>50</param-value> </init-param> <init-param> <param-name>org.apache.jetspeed.cache.validation.interval </param-name> <param-value>10000</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet> <servlet> <servlet-name>LoginProxyServlet</servlet-name> <servlet-class>org.apache.jetspeed.login.LoginProxyServlet </servlet-class> </servlet> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>org.apache.jetspeed.login.LoginServlet </servlet-class> </servlet> <servlet> <servlet-name>LoginErrorServlet</servlet-name> <servlet-class>org.apache.jetspeed.login.LoginErrorServlet </servlet-class> </servlet> <servlet> <servlet-name>LoginRedirectorServlet</servlet-name> <servlet-class>org.apache.jetspeed.login.LoginRedirectorServlet </servlet-class> </servlet> <servlet> <servlet-name>LogoutServlet</servlet-name> <servlet-class>org.apache.jetspeed.login.LogoutServlet </servlet-class> </servlet> <servlet> <servlet-name>ManagerServlet</servlet-name> <servlet-class>org.apache.jetspeed.manager.ManagerServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/portal/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/portlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/jetspeed/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/fileserver/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/ajaxapi/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/desktop/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jetspeed</servlet-name> <url-pattern>/action/*</url-pattern> </servlet-mapping> - <!-- Map *.vm files to Velocity --> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LoginProxyServlet</servlet-name> <url-pattern>/login/proxy</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login/login</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LoginErrorServlet</servlet-name> <url-pattern>/login/error</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LoginRedirectorServlet</servlet-name> <url-pattern>/login/redirector</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LogoutServlet</servlet-name> <url-pattern>/login/logout</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ManagerServlet</servlet-name> <url-pattern>/manager/*</url-pattern> </servlet-mapping> <!-- The Usual Welcome File List --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- JNDI Db resource --> <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/jetspeed</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <!-- Protect LogInRedirectory.jsp. This will require a login when called --> <security-constraint> <web-resource-collection> <web-resource-name>Login</web-resource-name> <url-pattern>/login/redirector</url-pattern> </web-resource-collection> <auth-constraint> <!-- the required portal user role name defined in: --> <!-- /WEB-INF/assembly/security-atn.xml --> <role-name>portal-user</role-name> </auth-constraint> </security-constraint> <!-- securing the ManagerServlet --> <security-constraint> <web-resource-collection> <web-resource-name>Manager</web-resource-name> <url-pattern>/manager/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> <!-- Login configuration uses form-based authentication --> <login-config> <auth-method>FORM</auth-method> <realm-name>Jetspeed</realm-name> <form-login-config> <form-login-page>/login/login</form-login-page> <form-error-page>/login/error</form-error-page> </form-login-config> </login-config> </web-app>
由于信息太多,這里只能選取重要的來解釋。首先,請(qǐng)注意名為jetspeed的servlet,這就是前面一個(gè)小節(jié)里提到的入口servlet,它同時(shí)也是Portal runtime的入口,它被映射到幾乎所有的URL Pattern。當(dāng)來自客戶端的Http請(qǐng)求滿足這些Pattern時(shí),jetspeed servlet將會(huì)觸發(fā)如下圖所示的處理流程:
請(qǐng)點(diǎn)擊這里查看Jetspeed runtime execution process的大圖
JetspeedServlet首先會(huì)通過RequestContextComponent為當(dāng)前Http Request創(chuàng)建RequestContext實(shí)例,然后在這個(gè)context下調(diào)用engine的service方法。然后就會(huì)進(jìn)入Pipeline的處理過程。
Pipeline
Jetspeed Pipeline實(shí)際上就是設(shè)計(jì)模式中常見的Chain of Responsibility模式的具體實(shí)現(xiàn),其設(shè)計(jì)概念類似Servlet Filter,一個(gè)封裝了HttpServletRequest和HttpServletResponse Object的Context在Pipeline中傳遞,每個(gè)valve都根據(jù)自己的需要從HttpServletRequest 對(duì)象中獲取信息并將處理的結(jié)果寫入context或HttpServletResponse對(duì)象,以傳遞給后面的valve使用。
這些Valve的定義和排序都是通過Spring Bean來配置的,定義文件為pipelines.xml,下面為該文件片斷截?。?div style="height:15px;">
<bean id="securityValve" class="org.apache.jetspeed.security.impl.SecurityValveImpl" init-method="initialize" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg> <ref bean="org.apache.jetspeed.profiler.Profiler" /> </constructor-arg> <constructor-arg> <ref bean="org.apache.jetspeed.security.UserManager" /> </constructor-arg> <constructor-arg> <ref bean="PortalStatistics" /> </constructor-arg> </bean>
<bean id="jetspeed-pipeline" class="org.apache.jetspeed.pipeline.JetspeedPipeline" init-method="initialize" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg> <value>JetspeedPipeline</value> </constructor-arg> <constructor-arg> <list> <ref bean="capabilityValve" /> <ref bean="portalURLValve" /> <ref bean="securityValve" /> <ref bean="localizationValve" /> <ref bean="passwordCredentialValve" /> <ref bean="loginValidationValve" /> <ref bean="profilerValve" /> <ref bean="containerValve" /> <ref bean="actionValve" /> <ref bean="DecorationValve" /> <ref bean="aggregatorValve" /> <ref bean="cleanUpValve" /> </list> </constructor-arg> </bean>
<bean id="pipeline-map" class="java.util.HashMap" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg> <map> <entry key="/portlet"> <value>portlet-pipeline</value> </entry> <entry key="/portal"> <value>jetspeed-pipeline</value> </entry> <entry key="/ajaxapi"> <value>ajax-pipeline</value> </entry> <entry key="/login"> <value>jetspeed-pipeline</value> </entry> <entry key="/fileserver"> <value>fileserver-pipeline</value> </entry> <entry key="/desktop"> <value>desktop-pipeline</value> </entry> <entry key="/action"> <value>desktop-action-pipeline</value> </entry> </map> </constructor-arg> </bean>
上面表格第一行定義了Security Valve,第二行定義了名為JetspeedPipeline的一個(gè)Pipeline,第三行定義了這些Pipeline對(duì)應(yīng)的URL Pattern。門戶開發(fā)者可以很容易的定義自己特有的Pipeline Valve(只需要實(shí)現(xiàn)org.apache.jetspeed.pipeline.valve.Valve接口,并在這個(gè)xml文件中定義它),或者改變現(xiàn)有Pipeline中valve執(zhí)行順序,甚至創(chuàng)建新的Pipeline,并把它映射到某個(gè)URL Pattern上。但這里需要注意的是新URL Pattern映射不能跟現(xiàn)有的重復(fù),這是因?yàn)橛成涫峭ㄟ^Map數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)。讓我們?cè)侔炎⒁饬Ψ祷氐綀D六,接下來的Container處理由一個(gè)豎線分隔,這是由于在Pipeline的aggregatorValve發(fā)生了cross context dispatch。需要注意的是Valve的實(shí)現(xiàn)類并不是Thread Safe的,開發(fā)者必須自己管理共享變量,最好就是不要定義對(duì)象成員變量,全部使用方法內(nèi)部變量。
Jetspeed的設(shè)計(jì)者之所以要自己實(shí)現(xiàn)這種鏈?zhǔn)侥J蕉恢苯邮褂肍ilter的可能原因有二:其一,F(xiàn)ilter是標(biāo)準(zhǔn)Servlet規(guī)范定義的接口,使用上肯定受規(guī)范限制,為了獲取更大的控制權(quán)和靈活度需要自己的Pipeline。其二, Application Server,由于每種應(yīng)用服務(wù)器可能對(duì)Filter的實(shí)現(xiàn)和配置方法上有異,為了實(shí)現(xiàn)一個(gè)Jetspeed Portal能夠在各種應(yīng)用服務(wù)器上發(fā)布并運(yùn)行,因而必須自己實(shí)現(xiàn)類似Filter的功能。
Container
講到這里,我們必須首先理清楚Portal和Portlet Container之間的關(guān)系。Portal并不等價(jià)于Portlet Container,一個(gè)企業(yè)級(jí)的門戶實(shí)現(xiàn),可以包含或者說支持多種Portlet Container同時(shí)運(yùn)行,例如IBM WebSphere Portal就既包含兼容JSR-168規(guī)范的Portlet Container又包含了支持一些IBM特有功能屬性的Portlet Container;BEA WebLogic也是采用相同策略,既有其舊有的基于Struts技術(shù)的Portlet Container,又支持JSR-168標(biāo)準(zhǔn)。隨著JSR標(biāo)準(zhǔn)規(guī)范進(jìn)一步深化完善,如JSR-286規(guī)范定稿,也許這些大的Portal廠商會(huì)逐漸放棄其舊的架構(gòu),完全擁抱標(biāo)準(zhǔn)。
對(duì)于Jetspeed而言,它同樣關(guān)注的是門戶本身的實(shí)現(xiàn),而不是Portlet Container的實(shí)現(xiàn),但由于Jetspeed-2完全拋棄Jetspeed-1的架構(gòu),而決定徹底擁抱標(biāo)準(zhǔn),因此Jetspeed只有一個(gè)標(biāo)準(zhǔn)的Portlet Container實(shí)現(xiàn),這就是Pluto項(xiàng)目。
Pluto的設(shè)計(jì)目標(biāo),其實(shí)既是一個(gè)完整的、自包含的輕量級(jí)門戶,又是一個(gè)易于內(nèi)置的Portlet Container。它不需要Jetspeed也能夠單獨(dú)工作,例如Apache唯一的應(yīng)用服務(wù)器項(xiàng)目Geronimo就內(nèi)置Pluto Portlet Container,作為它的Console實(shí)現(xiàn)平臺(tái)。然而,這與Jetspeed的定位起了沖突。在2005年底的Apache Con上,門戶項(xiàng)目組開發(fā)者齊聚一堂,就該問題作了深入的探討,也許這兩個(gè)項(xiàng)目在將來會(huì)更加關(guān)注于自身的技術(shù)領(lǐng)域。
Jetspeed所內(nèi)置的Pluto版本為穩(wěn)定的1.0.1版,它所提供的內(nèi)置集成方式不如目前尚未正式發(fā)布的Pluto1.1版本豐富,因此Jetspeed采用了Servlet 規(guī)范中的Cross Context Dispatch機(jī)制,將之集成了起來,這就是為什么Runtime架構(gòu)圖上,兩者要用豎線分隔開來,因?yàn)樗麄兤鋵?shí)是兩個(gè)完全不同的Web應(yīng)用,有著不一樣的Context設(shè)置,之間通過Cross Context Dispatch機(jī)制聯(lián)系起來的。因此當(dāng)門戶開發(fā)者需要在其它應(yīng)用服務(wù)器上部署Jetspeed門戶時(shí),必須注意開啟Cross Context Dispatch機(jī)制,也同時(shí)要注意這種使用方式所帶來的安全問題。例如Tomcat是通過設(shè)置文件%TOMCAT_ROOT%/conf/Catalina/localhost/jetspeed.xml(注意粉紅色高亮字體):
<Context path="/jetspeed" docBase="jetspeed" crossContext="true"> <Realm className="org.apache.catalina.realm.JAASRealm" appName="Jetspeed" userClassNames="org.apache.jetspeed.security.impl.UserPrincipalImpl" roleClassNames="org.apache.jetspeed.security.impl.RolePrincipalImpl" useContextClassLoader="false" debug="0" /> <Resource name="jdbc/jetspeed" auth="Container" factory="org.apache.commons.dbcp.BasicDataSourceFactory" type="javax.sql.DataSource" username="" password="" driverClassName="org.apache.derby.jdbc.EmbeddedDriver" url="jdbc:derby:/tmp/j2" maxActive="100" maxIdle="30" maxWait="10000" /> <Valve className="org.apache.catalina.authenticator.FormAuthenticator" characterEncoding="UTF-8" /> </Context>
在Pluto和Jetspeed相互配合下,通過JetspeedContainerServlet,最終執(zhí)行控制權(quán)會(huì)交給Portlet的實(shí)現(xiàn)類。JetspeedContainerServlet就定義在Portlet應(yīng)用程序所屬的Web應(yīng)用單位中,也就是說所有在Jetspeed中運(yùn)行的Portlet Web應(yīng)用都必須在Web.xml中包含JetspeedContainerServlet的定義。在Tomcat中,這是通過deploy-tool組件完成的,在其它應(yīng)用服務(wù)器平臺(tái),很可能就要靠應(yīng)用發(fā)布者手動(dòng)添加了,需添加的信息包含:
<servlet> <servlet-name>JetspeedContainer</servlet-name> <display-name>Jetspeed Container</display-name> <description>MVC Servlet for Jetspeed Portlet Applications</description> <servlet-class>org.apache.jetspeed.container. JetspeedContainerServlet</servlet-class> <init-param> <param-name>contextName</param-name> <param-value>rss</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JetspeedContainer</servlet-name> <url-pattern>/container/*</url-pattern> </servlet-mapping> <taglib> <taglib-uri>http://java.sun.com/portlet</taglib-uri> <taglib-location>/WEB-INF/tld/portlet.tld</taglib-location> </taglib>
Jetspeed Portlet Extension Service
前面介紹了實(shí)現(xiàn)架構(gòu)和運(yùn)行時(shí)架構(gòu),接下來我們一起來看看Jetspeed為Portlet應(yīng)用提供的Jetspeed Service架構(gòu)。如果了解JSR-168規(guī)范的開發(fā)者就會(huì)知道,這個(gè)規(guī)范是基于Servlet 2.3規(guī)范基礎(chǔ)上的一個(gè)簡單擴(kuò)展,因此并沒有對(duì)Portlet開發(fā)提供任何特別的支持。因而每家Portal廠商都提供了自己的擴(kuò)展。
Jetspeed提供的擴(kuò)展方式跟很多廠商對(duì)Servlet規(guī)范的擴(kuò)展一樣,定義了一個(gè)名為jetspeed-portlet.xml的文件,作為標(biāo)準(zhǔn)的portlet.xml的擴(kuò)展。只要你在打包發(fā)布portlet應(yīng)用時(shí)將這個(gè)文件與portlet.xml放在一起,Jetspeed的發(fā)布程序就會(huì)自動(dòng)讀取這個(gè)文件,并根據(jù)其內(nèi)容執(zhí)行一系列的操作。它們的關(guān)系如同BEA Weblogic應(yīng)用服務(wù)器里面的weblogic.xml與web.xml;JBoss應(yīng)用服務(wù)器里面的jboss-web.xml與web.xml。
下面我們來看看這個(gè)文件的格式:
<portlet-app id="j2-admin" version="1.0" xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" xmlns:js="http://portals.apache.org/jetspeed" xmlns:dc="http://www.purl.org/dc"> <js:services> <js:service name="ApplicationServerManager" /> <js:service name="DeploymentManager" /> <js:service name="EntityAccessor" /> <js:service name="GroupManager" /> <js:service name="PageManager" /> <js:service name="PermissionManager" /> <js:service name="PortalAdministration" /> <js:service name="PortletFactory" /> <js:service name="PortalAdministration" /> <js:service name="PortletRegistryComponent" /> <js:service name="PortalStatistics" /> <js:service name="Profiler" /> <js:service name="RoleManager" /> <js:service name="SearchComponent" /> <js:service name="SSO" /> <js:service name="UserManager" /> <js:service name="HeaderResource" /> </js:services> </portlet-app>
跟據(jù)XML Element的名字,可以理解就是提供給j2-admin這個(gè)Portlet應(yīng)用程序使用的一些Services。那么這些Services是怎么定義的呢?以UserManager這個(gè)服務(wù)為例,首先回到前面提到過的assemble目錄下,找到j(luò)etspeed-services.xml和security-managers.xml,下面分別是它們的內(nèi)容節(jié)選:
jetspeed-services.xml
<beans default-lazy-init="false" default-dependency-check="none" default-autowire="no"> <!-- Portlet Services --> <bean id="PortalServices" class="org.apache.jetspeed.services.JetspeedPortletServices" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg> <map> <entry key="SearchComponent"> <ref bean="org.apache.jetspeed.search.SearchEngine" /> </entry> <entry key="UserManager"> <ref bean="org.apache.jetspeed.security.UserManager" /> </entry> <entry key="PageManager"> <ref bean="org.apache.jetspeed.page.PageManager" /> </entry> </map> </constructor-arg> </bean> </beans>
security-managers.xml
<beans default-lazy-init="false" default-dependency-check="none" default-autowire="no"> <bean id="org.apache.jetspeed.security.UserManager" class="org.apache.jetspeed.security.impl.UserManagerImpl" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <constructor-arg> <ref bean="org.apache.jetspeed.security.SecurityProvider" /> </constructor-arg> </bean> </beans>
由上面的兩個(gè)文件,我們可以清楚地看出UserManager是定義security-managers.xml文件中的,但是為了能夠在portlet服務(wù)中引用它,還必須在jetspeed-services.xml中再次引用它的bean name,org.apache.jetspeed.services.JetspeedPortletServices封裝了一個(gè)Map數(shù)據(jù)結(jié)構(gòu),Map中存放的就是服務(wù)名稱和該服務(wù)POJO對(duì)象引用,這一切便利都是由Spring帶來的。
下面是在Portlet的代碼中使用該服務(wù)的例子:
protected UserManager userManager = null; public void init(PortletConfig config) throws PortletException { super.init(config); userManager = (UserManager) getPortletContext().getAttribute(CommonPortletServices. CPS_USER_MANAGER_COMPONENT); if (null == userManager) { throw new PortletException("Failed to find the User Manager on portlet initialization"); } }
Jetspeed鼓勵(lì)Portlet開發(fā)者在開發(fā)過程中,將公共的Service用Spring Bean的方式封裝起來,然后添加到Jetspeed-services中,這樣就可以在Portlet代碼中輕松復(fù)用這些公共Service了,并且還可以利用Spring來管理這些Service的生命周期。事實(shí)上,Jetspeed自帶管理界面Portlet應(yīng)用程序就大量采用了這種技術(shù)。
還有一個(gè)需要注意的問題是,用戶自定義的Service必須放到Tomcat的shared\lib下面去,以保證JAVA Classloader能夠找到它。
介紹了那么多Jetspeed架構(gòu)方面的信息,下面我們一起來快速瀏覽一下Jetspeed Portal的核心組件。
Jetspeed-Api
路徑:components/jetspeed-api
定義幾乎所有的jetspeed-api interfaces,一般的開發(fā)者都使用這個(gè)組件中定義的接口進(jìn)行二次開發(fā)。
Component Manager
路徑:components/cm
Jetspeed組件管理器,通過接口org.apache.jetspeed.components.ComponentManager屏蔽了Spring的實(shí)現(xiàn)細(xì)節(jié)??梢酝ㄟ^實(shí)現(xiàn)該接口替換Spring。
Deploy-Tool
路徑:components/deploy-tool
當(dāng)Web Container為Tomcat時(shí),通過該組件,讀取已打包好的portlet應(yīng)用程序中的portlet.xml和web.xml,檢查是否包含JetspeedContainerServlet的定義,如果沒有則修改web.xml加入這部分信息。
Id-Generator
路徑:components/id-generator
用于生成全局唯一的portlet實(shí)例id。
Locator
路徑:components/locator
提供定位門戶資源的服務(wù),資源包括:模板,Profiler等。
Page-Manager
路徑:components/page-manager
對(duì)著名的門戶結(jié)構(gòu)描述文件-PSML(Portal Structure Markup Language),提供了Java對(duì)象模型映射,并且支持文本風(fēng)格的PSML和數(shù)據(jù)庫風(fēng)格的PSML,以及PSML管理器。
Portal
路徑:components/portal
實(shí)現(xiàn)絕大部分的jetspeed-api組件中定義的interface,是最核心的組件。
Preferences
路徑:components/prefs
實(shí)現(xiàn)了Portlet屬性偏好功能,提供將這些屬性持久化到數(shù)據(jù)庫的服務(wù)。
RDBMS
路徑:components/rdbms
Jetspeed中所有與Apache OJB O/R Mapping框架有關(guān)的組建的基礎(chǔ)組件。
Search
路徑:components/search
提供整個(gè)門戶資源的全文本搜索服務(wù),具體實(shí)現(xiàn)依賴于Apache Lucene。
Security
路徑:components/security
提供基于標(biāo)準(zhǔn)JAAS的認(rèn)證服務(wù),支持?jǐn)?shù)據(jù)庫和LDAP作為認(rèn)證信息倉庫?;诮巧氖跈?quán)服務(wù),默認(rèn)支持?jǐn)?shù)據(jù)庫作為權(quán)限倉庫。
Single Sign-on
路徑:components/sso
提供一個(gè)可擴(kuò)展的單點(diǎn)登陸服務(wù)接口和一個(gè)簡單的基于JAAS Subject的實(shí)現(xiàn),該組件主要提供Portal門戶與后臺(tái)應(yīng)用之間的單點(diǎn)登陸功能。
Statistics
路徑:components/statistics
提供一個(gè)簡單的訪問請(qǐng)求統(tǒng)計(jì)服務(wù)的實(shí)現(xiàn),支持將統(tǒng)計(jì)信息持久化到數(shù)據(jù)庫。在Jetspeed-2管理界面中,還提供了專門的Portlet瀏覽這些統(tǒng)計(jì)信息。
本文帶讀者瀏覽了Apache Portal項(xiàng)目組的所有成員,并著重介紹了Apache Jetspeed-2 Portal。希望能夠使不了解門戶技術(shù)的朋友對(duì)它有一個(gè)初步的認(rèn)識(shí),找到自己感興趣的方向,繼續(xù)深入研究;同時(shí)對(duì)那些試圖在項(xiàng)目中使用開源軟件的開發(fā)者,提供一些可以借鑒的信息??v觀目前開源軟件中的門戶實(shí)現(xiàn),還沒有哪一個(gè)社區(qū)能夠提供像Apache Portal項(xiàng)目組這樣完整的解決方案同時(shí),還擁有如此友好的許可策略。只要去深入了解,開源軟件往往能夠給人們帶來意外的驚喜。
Apache Portal項(xiàng)目組首頁:你可以在這里找本文中提到的所有項(xiàng)目信息。
JSR 168: Portlet SpecificationJSR 286: Portlet Specification 2.0
OASIS Web Services for Remote Portlets (WSRP) TC
WebSphere Portal Server:IBM公司著名的門戶產(chǎn)品
Spring Framework:開源社區(qū)里面最著名的POJO和IoC框架
Apache Tomcat:Jetspeed默認(rèn)的支持的應(yīng)用服務(wù)器
Apache Geronimo:Apache推出的兼容標(biāo)準(zhǔn)JEE規(guī)范的應(yīng)用服務(wù)器,同時(shí)也是開源軟件商用化的成功典范,IBM公司的WebSphere Community Edition就是基于該開源項(xiàng)目的。
Apache ObjectRelationalBridge:這是Jetspeed用于訪問數(shù)據(jù)庫的O/R Mapping實(shí)現(xiàn)。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Liferay系列文章(四)Portal產(chǎn)品介紹--開放源碼Portal產(chǎn)品
liferay二次開發(fā)指南
GenericMVCPortlet xref
關(guān)于Liferay的配置文件 —— 基于Struts開發(fā)Portlet
SSH實(shí)現(xiàn)的增刪改查實(shí)例
有話好好說: 幾種開源Portal的簡單介紹分析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服