煩惱歲月

          付出總是有回報(bào)的 take action follow your heart , or follow your head
          posts - 40, comments - 5, trackbacks - 0, articles - 4

          JetSpeed2.0 概述

          Posted on 2007-11-13 11:10 不需要解釋 閱讀(5686) 評(píng)論(0)  編輯  收藏 所屬分類: jetspeed
           

          Jetspeed2.0最終release版本發(fā)布于200512月, 可以從以下網(wǎng)址下載源代碼和捆綁tomcat的壓縮文件: http://www.apache.org/dist/portals/jetspeed-2/   。

          Jetspeed1.x比較,Jetspeed2.0 (以下簡(jiǎn)稱J2)的架構(gòu)發(fā)生了很大變化, J1.x使用了Turbine,在J2Turbine不再使用,  而是使用了Spring Framework作為默認(rèn)的組件框架,從官方的資料介紹看,J2架構(gòu)支持將一種組件架構(gòu)替換為別的組建架構(gòu)如PicoSpring僅僅是J2默認(rèn)的Component Framework,從本節(jié)下文的敘述中可以看到替換的方式。

          portlet 之間可以通過session等來進(jìn)行交互。所以談不上 “JSR 168沒有定義portlet之間的事件模型”。 由于Jetspeed不是基于JSF的,所以它的門戶上的鏈接是無狀態(tài)的,也許獨(dú)立的AJAX可以讓它更容易被集成。

          Jetspeed-2使用pluto作為Portlet 容器。

          Jetspeed-2組件框架(Component Framework)的裝配是通過JetspeedServletorg.apache.jetspeed.engine.JetspeedServlet)進(jìn)行配置和實(shí)現(xiàn)的,見下圖:

          JetspeedServletweb.xml中配置,門戶應(yīng)用啟動(dòng)時(shí)即執(zhí)行JetspeedServlet。JetspeedServletinitializeComponentManager方法為給定的組件框架裝載assemply(見WEB-INF/assembly),initializeComponentManager將spring framework作為默認(rèn)的組件框架。并裝配WEB-INF/assembly下的xml文件來初始化spring引擎。然后組件框架來創(chuàng)建JetspeedEngin:

          engine = new JetspeedEngine(properties, applicationRoot, config,

          initializeComponentManager(config, applicationRoot, properties));

          下面是initializeComponentManager方法的代碼:

           

          protected ComponentManager initializeComponentManager(ServletConfig servletConfig, String appRoot, Configuration configuration) throws IOException

          {

          ServletConfigFactoryBean.setServletConfig(servletConfig);

          // String relativeApplicationRoot = getRealPath("/");

          String relativeApplicationRoot = appRoot;

          String absApplicationRoot = new

          File(relativeApplicationRoot).getCanonicalPath();              

          final String assemblyDir =

          configuration.getString("assembly.dir","/WEB-INF/assembly");

          final String assemblyFileExtension =

          configuration.getString("assembly.extension",".xml");

                 

          String[] bootConfigs = new String[] {"/WEB-INF/assembly/boot/*.xml"};

          String[] appConfigs = new String[] {assemblyDir+"/*"+assemblyFileExtension};

          ServletContext servletContext = servletConfig.getServletContext();

          SpringComponentManager cm = new SpringComponentManager(bootConfigs,

          appConfigs, servletContext, appRoot);   

          return cm;       

          }

          如果我們需要用別的組件框架替代Spring framework,就要覆蓋initializeComponentManager方法,就是指用別的ComponentManager替代SpringComponentManager。下面是CompomentManager相關(guān)的類圖:

          從上面的分析說明Jetspeed2的基礎(chǔ)組架構(gòu)是基于Spring組件的可伸縮的架構(gòu),Jetspeed2還有什么其他新的特性?

          l               Jetspeed 2.0 final release版本完全兼容Portlet規(guī)范1.0(JSR-168)Jetspeed2.0Java Portlet API的完整實(shí)現(xiàn)。

          l               支持SSOSingle Sign-On)單點(diǎn)登錄, 單點(diǎn)登錄技術(shù)是一種認(rèn)證和授權(quán)機(jī)制,它允許注冊(cè)用戶只需要在任一成員網(wǎng)站上登錄一次,而后授權(quán)訪問其他連接的分支網(wǎng)站,無需再進(jìn)行登錄。

          l               Jetspeed-Bridge使Jetspeed可以集成Struts,JSF,PHP,Perl,Velocity,WebWork開發(fā)的應(yīng)用。可以將Struts Action、Velocity模板、Perl腳本、PHP腳本等以Portlet的形式展現(xiàn),這對(duì)舊系統(tǒng)的移植將很有幫助。JetSpeed 2.0還實(shí)現(xiàn)了一組常用的示例Portlet,包括日歷、書簽等小工具。

          l               可配置的管道請(qǐng)求處理器(Pipeline Request Processor)。管道可把一些訪問的請(qǐng)求根據(jù)參數(shù),分配給portlet的容器。

          l               JAAS數(shù)據(jù)庫安全策略。

          l               Jetspeed支持AJAX XML API。

          l               portlet應(yīng)用的自動(dòng)部署。

          l               基于LDAP及數(shù)據(jù)庫實(shí)現(xiàn)的安全組件。為用戶認(rèn)證提供LDAP支持。

          l               開發(fā)者可使用Jetspeed PSML語言裝配portlets。

          l               門戶內(nèi)容管理和導(dǎo)航:頁面、菜單、文件夾、鏈接。

          l               多線程的聚合引擎。

          l               集成主流的數(shù)據(jù)庫:Derby, MySQL, MS SQL, Oracle, Postgres, DB2

          l               國際化支持

          l               統(tǒng)計(jì)日志引擎。

          l               Portlet注冊(cè)

          l               使用Lucene對(duì)Portlet組件進(jìn)行全文搜索。

          l               用戶注冊(cè)功能

          l               遺忘密碼獲取功能

          l               豐富的登錄和口令配置管理功能

          l               基本頁面定制

          l               管理Portlet:

          -          用戶、角色、組、密碼和Profile管理

          -          JSR168 用戶屬性編輯器

          -          Portlet應(yīng)用和生命周期管理

          -          Profiler系統(tǒng)管理

          -          統(tǒng)計(jì)報(bào)表

          門戶設(shè)計(jì)的特征:

          l               可部署Jetspeed Portlet和頁面皮膚(Decorators)CSS組件。

          l               可配置的CSS頁面外觀(Layouts)。

          l               很容易為皮膚和Layouts組件使用Velocity宏語言

          Jetspeed-2 工作流程

          引擎部分是Jetspeed-2,而Container是Pluto Portlet Container,Portlet就是自己寫的Portlet;所以這張圖正好對(duì)照J(rèn)SR168中的Portal—Portlet Container—Portlet的概念。

          上圖描述的的工作流程:

          1、request送至server后由JetspeedServlet(org.apache.jetspeed.JetspeedServlet)接收。JetspeedServlet通過Jetspeed(org.apache.jetspeed.Jetspeed)取得ComponentManager,然后通過ComponentManager取得

          RequestContextComponent(org.apache.jetspeed.request.JetspeedRequestContextComponent) 。

          2RequestContextComponent會(huì)針對(duì)這個(gè) request建立一個(gè)

          RequestContext(org.apache.jetspeed.JetspeedRequestContext),并且讓這個(gè)request和新建的RequestContext能互相參照。

          3
          呼叫Engine(org.apache.jetspeed.JetspeedEngine)service()方法,這個(gè)方法會(huì)把剛剛建立的RequestContext傳入,這樣后面的組件才能使用。

          4
          、service()方法中,Engine會(huì)依據(jù)request的目標(biāo)URL來取得相對(duì)應(yīng)的Pipeline(org.apache.jetspeed.pipelineJetspeedPipeline)來處理。Pipeline使用了chain of responsibilitypattern,是由一堆Valve(org.apache.jetspeed.pipeline.valve.Valve)串起來的。

          5
          、各個(gè)Valve依序執(zhí)行,其中某些Valve會(huì)和Container動(dòng)作,某些Valve會(huì)負(fù)責(zé)產(chǎn)生要responseportal頁面。在這個(gè)過程中,Continer會(huì)執(zhí)行相關(guān)的Portlet,并將結(jié)果返回至Pipeline,也就是Valve chain中。

          6
          、將產(chǎn)生的portal頁面?zhèn)骰亟ouser,流程結(jié)束。

          由上面的介紹,應(yīng)該可以體會(huì)到Pipeline在J2中是非常重要的,這里附上Pipeline的官方UML圖做參考。

          Jetspeed-2本身是Spring-based的架構(gòu),主要的Spring設(shè)定都在webapps"jetspeed"WEB-INF"assembly下。JetspeedServlet在init時(shí)會(huì)建立Spring容器并載入這些xml文件,而之前提到的ComponentManager就可以通過name或class在Spring容器中尋找需要的component。有關(guān)J2的component,請(qǐng)務(wù)必參考http://portals.apache.org/jetspeed-2/guides/guide-components.html及源代碼。

             
          看一下assembly目錄中的pipelines.xml。這個(gè)XML是用來組合各個(gè)Pipeline和設(shè)定各Pipeline和其對(duì)應(yīng)的URL。先看一下最后一段bean id="pipeline-map"的部份,在這邊可以看到URL和其相對(duì)應(yīng)的Pipeline。另外找到bean id="jetspeed-pipeline"這一段,可以看到這個(gè)Pipeline中Valve的組合,而這個(gè)Pipeline也是default的Pipeline;有興趣的不妨參這個(gè)XML文件,把這個(gè)Pipeline中的Valve的原始代碼找到翻一翻,大致了解一下每個(gè)Valve在做啥。
           

          Jetspeed-2性能:

          在jetspeed2中還使用了多線程異步處理,用以提高Performance. 但是事實(shí)上第一次運(yùn)行的開銷還是挺大的,比如一個(gè)Portal頁面上有20個(gè)Portlet,那么Portlet Container就需要初始20個(gè)web application. 加載class總是很耗資源的. 目前沒有十分好的方法。

          Jetspeed-2安全機(jī)制


          J2使用JAAS的來處理security有關(guān)的問題。在j2捆綁的tomcat中,從bin同級(jí)別目錄conf中查找Catalina"localhost"jetspeed.xml,打開這個(gè)文件可看到有關(guān)JAAS Realm及l(fā)ogin的設(shè)定。

          tomcat"conf" l及C:"tomcat"webapps"jetspeed"WEB-INF"web.xml看到有關(guān)及l(fā)ogin的設(shè)定 :
          <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="sa" password=""

                      driverClassName="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://127.0.0.1:9001"

                      maxActive="100" maxIdle="30" maxWait="10000"/>

          </Context>

          大致上來說,JAAS包含Principal、Permission、Policy三個(gè)概念。在J2中有user、role、group三種Principal。而Permission基本上有page、portlet,tab等等,當(dāng)然也可以增加自定的Permission。至于Policy,J2并沒有使用JAAS的policy,而是使用自帶的RdbmsPolicy,也就是把Policy的信息存在資料庫中;而通過適當(dāng)?shù)脑O(shè)置, J2也可以使用相關(guān)App Server的JAAS。

          底下是官方的security組加的架構(gòu)圖:

          在J2中,核心的部份就是"J2 Security Coarsed Services"里的4個(gè)Manager組件:UserManager,RoleManager,GroupManager,PermissionManager, J2的JAAS login module實(shí)際上是使用UserManager來進(jìn)行authentication;UserManager通過OJB自數(shù)據(jù)庫中取出user的信息例如UserPrincipal、Crendential等并進(jìn)行authorization.
             
          J2在security的部份也提供了SPI的設(shè)計(jì)供開發(fā)人員加入自定的認(rèn)證方式,例如使用LDAP,參考底下官方的連接:

          http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/ldap.html ,可以知道如何使LDAP來進(jìn)J2上的認(rèn)證。
           

          Jetspeed-2的Portal Bridge

          隨著Portal一步步走向成熟其結(jié)構(gòu)和功能也發(fā)生了較大變化,從混和型服務(wù)走向以系統(tǒng)框架為核心,應(yīng)用程序與部署、開發(fā)完全分開的階段,Portal相當(dāng)與一個(gè)骨架一樣可以接納外部的這種技術(shù)架構(gòu)開發(fā)的應(yīng)用程序,使用Portals Bridges模式來連接不同的應(yīng)用程序,可包括下幾種:

          集成Struts MVC模式開發(fā)的應(yīng)用程序;

          集成WebWorks開發(fā)的應(yīng)用程序;

          集成JSF開發(fā)的應(yīng)用程序;

          集成Perl開發(fā)的應(yīng)用程序;

          集成PHP開發(fā)的應(yīng)用程序;

          1 集成Struts MVC模式開發(fā)的應(yīng)用程序

          Struts已經(jīng)成為了用Java創(chuàng)建Web應(yīng)用的一個(gè)最流行的框架工具,Struts所實(shí)現(xiàn)的MVC模式給Web應(yīng)用帶來了良好的層次劃分,同時(shí)也提供了一系列的工具來簡(jiǎn)化Web應(yīng)用的開發(fā)。

          應(yīng)用程序開發(fā)者無需關(guān)心Portal的規(guī)范,只要關(guān)心Struts本身的開發(fā),這樣大大降低了開發(fā)成本和開發(fā)人員的再培訓(xùn)

          主要實(shí)現(xiàn)類:public class StrutsPortlet extends GenericPortlet。

          下面是Portlet的片斷:

          <portletid="StrutsPortletDemo">

           <init-param>

             <name>ServletContextProvider</name>

           <value>org.apache.jetspeed.portlet.ServletContextProviderImpl</value>

           </init-param>

           <init-param>

          <name>ViewPage</name>

           <value>/Welcome.do</value>

           </init-param>

              <init-param>

                <name>HelpPage</name>

                <value>/Tour.do</value>

              </init-param>

              <portlet-name>StrutsPortletDemo</portlet-name>

              <display-name>Struts Portlet Demo</display-name>

              <description>This is the struts MailReader portlet demo</description>

              <portlet-class>org.apache.portals.bridges.struts.StrutsPortlet</portlet-class>

              <expiration-cache>-1</expiration-cache>

              <supports>

                <mime-type>text/html</mime-type>

                <portlet-mode>VIEW</portlet-mode>

                <portlet-mode>HELP</portlet-mode>

           </supports>

           2 集成WebWork開發(fā)的應(yīng)用程序

          WebWork是一個(gè)源代碼開放的Web應(yīng)用框架,用于簡(jiǎn)化基于Web的應(yīng)用開發(fā)。使用WebWorkJavaServerPagesJSP)、Velocity來建立注冊(cè)界面。通過Jetspeed2Portals Bridges框架來實(shí)現(xiàn)和webwork的集成,主要實(shí)現(xiàn)類

          public class Webwork2Portlet extends GenericPortlet

          3 JSP應(yīng)用程序集成

          JSF為廣大基于JAVA Web應(yīng)用用戶界面的開發(fā)人員提供了標(biāo)準(zhǔn)的編程接口、豐富可擴(kuò)展的UI組件庫(一個(gè)核心的JSP標(biāo)記庫用來處理事件、執(zhí)行驗(yàn)證以及其他非UI相關(guān)的操作和一個(gè)標(biāo)準(zhǔn)的HTML 標(biāo)記庫來表示 UI組件)、事件驅(qū)動(dòng)模型等一套完整的Web應(yīng)用框架,通過 JSF ,您可以在頁面中輕松自如地使用 WEB 組件、捕獲用戶行為所產(chǎn)生的事件、執(zhí)行驗(yàn)證、建立頁面導(dǎo)航…,同時(shí)您會(huì)發(fā)現(xiàn),當(dāng)使用支持JSF的開發(fā)工具來開發(fā) JSF 應(yīng)用的時(shí)候,一切將會(huì)變得異常簡(jiǎn)單,就類似于我們現(xiàn)在開發(fā)VB或者PowerBuilder程序一樣的簡(jiǎn)便,GUI方式拖放組件、修改組件屬性、建立組件間關(guān)聯(lián)以及編寫事件偵聽器等等,這樣,一個(gè)并不是特別熟悉JavaWeb應(yīng)用開發(fā)人員也能夠輕松地完成自己的任務(wù)了,這種易開發(fā)性對(duì)于J2EE而言無疑是太重要了。

          3 集成PERL應(yīng)用程序

          Perl 就是 Practical Extraction and Reporting Language 的簡(jiǎn)稱,是一種最廣泛應(yīng)用于語法分析和 World Wide Web 的編程語言。它起源于 awk、C、sh sed 語言,然而,它的應(yīng)用開發(fā)遠(yuǎn)比其他任何一種面向?qū)ο缶幊陶Z言更加容易。

          實(shí)現(xiàn)方法

          public class PerlPortlet extends GenericPortlet

          直接通過HttpServletResponseWrapper來封裝獲取Response的字節(jié)流

          Portlet的配置的片斷:

          <portlet-name>perl-demo</portlet-name>

             <display-name>Perl demo Portlet</display-name>

             <portlet-class>org.apache.portals.bridges.perl.PerlPortlet</portlet-class>

           <expiration-cache>-1</expiration-cache>

             <supports>

            <mime-type>text/html</mime-type>

                <portlet-mode>VIEW</portlet-mode>

           </supports>

           <portlet-info>

          4 集成PHP應(yīng)用程序

          PHP是一個(gè)基于服務(wù)端來創(chuàng)建動(dòng)態(tài)網(wǎng)站的腳本語言,您可以用PHPHTML生成網(wǎng)站主頁。當(dāng)一個(gè)訪問者打開主頁時(shí),服務(wù)端便執(zhí)行PHP的命令并將執(zhí)行結(jié)果發(fā)送至訪問者的瀏覽器中,這類似于ASPCoildFusion,然而PHP和他們不同之處在于PHP開放源碼和跨越平臺(tái),PHP可以運(yùn)行在WINDOWS NT和多種版本的UNIX上。它不需要任何預(yù)先處理而快速反饋結(jié)果,它也不需要mod_perl的調(diào)整來使您的服務(wù)器的內(nèi)存映象減小。PHP消耗的資源較少,當(dāng)PHP作為Apache Web服務(wù)器一部分時(shí),運(yùn)行代碼不需要調(diào)用外部二進(jìn)制程序,服務(wù)器不需要承擔(dān)任何額外的負(fù)擔(dān)。實(shí)現(xiàn)類:

          public class PHPApplicationPortlet extends GenericPortlet

          相關(guān)技術(shù)介紹和規(guī)范

          WSRP

          WSRP由OASIS(一個(gè)由開發(fā)電子商務(wù)標(biāo)準(zhǔn)的行業(yè)專家所組成的非贏利性社團(tuán))創(chuàng)建,它規(guī)定Porlet的遠(yuǎn)程渲染(rendering)。主要目的就是為網(wǎng)絡(luò)服務(wù)提供視覺化和使用者面對(duì)面服務(wù)的主要構(gòu)件。WSRP最重要的特性就是它具有隨插隨用(plug-and-play)的功能,可以讓互聯(lián)網(wǎng)門戶或其他網(wǎng)絡(luò)應(yīng)用(如手機(jī),PDA等)從網(wǎng)絡(luò)不同的來源處將多樣內(nèi)容或是應(yīng)用聚集起來。WSRP使獲得原來極難實(shí)現(xiàn)的功能成為可能。例如,部署一次,但把它們傳遞到任何地方,將第三方的Portlet整合在一起,增強(qiáng)來自不同開發(fā)商的門戶之間的互操作性。WSRP也為客戶提供了一種構(gòu)建聯(lián)合門戶的可行方法。聯(lián)合門戶由互操作的門戶網(wǎng)絡(luò)組成,由此,某一門戶托管的資源可以被許多門戶使用。采用聯(lián)合門戶有無數(shù)的好處,包括門戶合理化和更少的IT管理的Web資產(chǎn)。

           過去,一個(gè)Portlet只能被托管它的同一門戶本地使用。而有了WSRP,則可以將一個(gè)Portlet從門戶表面(“使用”)的Portlet交給物理上、邏輯上獨(dú)立的基礎(chǔ)設(shè)施托管(“生產(chǎn)”)。由于這種革新,WSRP具有從根本上增強(qiáng)門戶部署靈活性的潛能。因?yàn)殚T戶能夠從任何地方的Portlet中提取內(nèi)容,所以業(yè)務(wù)部門現(xiàn)在可以編寫和維護(hù)他們自己的Portlet。這可以在各個(gè)業(yè)務(wù)部門的本地基礎(chǔ)設(shè)施上完成,所以某一單個(gè)門戶內(nèi)的所有portlet不必部署在單個(gè)門戶實(shí)例上。由于防火墻或者不同部署方案而一度難以更新和修改的內(nèi)容,現(xiàn)在可以由各業(yè)務(wù)部門方便而快捷地進(jìn)行。業(yè)務(wù)部門獲得了前所未有的獨(dú)立性和靈活性。WSRP拓寬了門戶可以利用的資源范圍。Porlet可以被所有J2EE門戶或者所有運(yùn)行.Net的機(jī)器生產(chǎn)或者使用。整個(gè)企業(yè)都可以利用現(xiàn)有的Portlet,而不再受開發(fā)商制約,并且減少了IT方面的費(fèi)用,節(jié)約了托管和部署重復(fù)portlet的時(shí)間。

           對(duì)程序員簡(jiǎn)而言之,開發(fā)符合WSRP規(guī)范的Portlet在發(fā)布和注冊(cè)后將可以供別人的Portal系統(tǒng)遠(yuǎn)程使用。


             
          盡管WSRP提出的遠(yuǎn)景如此美妙,但由于WebService的復(fù)雜性,盡管已有一些廠商的產(chǎn)品支持WSRP,但實(shí)際使用中非常少。

          Portlet容器

          Portlet Container用來管理Portlet的生命周期并且提供其運(yùn)行所需要的必要環(huán)境.。并且為Portlet Preferences提供持久性(Persistent)存取服務(wù),但是其不支持內(nèi)容的Aggregation.。AggregationPortal組件提供。

          Portlet

          一個(gè) Portlet 是以 Java 技術(shù)為技術(shù)的 Web 組件,由 Portlet Container 所管理,專門處理客戶的 request 以及產(chǎn)生各種動(dòng)態(tài)的信息內(nèi)容。Portlets 為可插式 ( pluggable ) 的客戶界面組件,提供呈現(xiàn)層成為一個(gè)信息系統(tǒng)。

          這些由 portlet 產(chǎn)生的內(nèi)容也被稱為片段 (fragment),而片段是具有一些規(guī)則的Markup( HTML、XHTML、WML ),而且可以和其他的片段組合而成一個(gè)復(fù)雜的文件。而 Portlet 中的內(nèi)容正常來說是與其他 Portlet 的內(nèi)容聚合而成為一個(gè) Portal 網(wǎng)頁。而 Portlet 的生命周期是被 Portlet Container 所管理控制的。

          客戶端和 portlets 的互動(dòng)是由 portal 通過典型的 request/response 方式實(shí)現(xiàn),正常來說,客戶會(huì)和 portlets 所產(chǎn)生的內(nèi)容互動(dòng),舉例來說,根據(jù)下一步的連接或者是確認(rèn)送出的表單,結(jié)果 portal 將會(huì)接收到 portlet 的動(dòng)作,將這個(gè)處理狀況轉(zhuǎn)向到目標(biāo) portlet。這些 portlet 內(nèi)容的產(chǎn)生可能會(huì)因?yàn)椴煌氖褂谜叨胁煌淖兓?,完全是根?jù)客戶對(duì)于這個(gè) portlet 的設(shè)置。

          Portlet生命周期
          Portlet
          接口的四個(gè)方法構(gòu)成一個(gè)完整的生命周期:
          public void init(PortletConfig config) throws PortletException;
              
          由Portlet容器調(diào)用,在將Portlet放入服務(wù)區(qū)前調(diào)用。Portlet容器在初始Portlet后,直接調(diào)用這個(gè)方法。
          public void processAction (ActionRequest request, ActionResponse response) throws PortletException, java.io.IOException;
              由Portlet容器調(diào)用,用來處理action request。
          public void render (RenderRequest request, RenderResponse response) throwsPortletException, java.io.IOException;
              
          由Portlet容器調(diào)用,用來生成輸出。
          public void destroy() ;
              
          將Portlet從服務(wù)區(qū)中刪除。

          一個(gè)Portal處理流程:

          1.  一個(gè)客戶端(例如:一個(gè)web瀏覽器)在被驗(yàn)證之后向Portal發(fā)出HTTP請(qǐng)求;

          2.  Portal(或稱為Portal Server)接收到請(qǐng)求;

          3.  Portal判斷請(qǐng)求是否包含與組成門戶網(wǎng)站網(wǎng)頁的portlet有關(guān)的動(dòng)作;

          4.  如果存在與某個(gè)portlet相關(guān)的動(dòng)作,Portal請(qǐng)求portlet容器調(diào)用portlet處理動(dòng)作;

          5.  Portal通過portlet容器調(diào)用portlet,獲得被包含在產(chǎn)生的門戶網(wǎng)站網(wǎng)頁中的內(nèi)容片段;

          6.  Portal將portlet產(chǎn)生的結(jié)果聚集于門戶網(wǎng)站的網(wǎng)頁,然后將網(wǎng)頁返回至客戶端。

          在下圖中需要注意的是Portal服務(wù)器是建立在Http服務(wù)器的基礎(chǔ)上的。Portal服務(wù)器不可獨(dú)立的運(yùn)行。

          Portlet Preferences

          Portlet PreferencesPortlet的一個(gè)新特性,提供類似數(shù)據(jù)庫的功能。但是不是用來取代數(shù)據(jù)庫,只是用來存取簡(jiǎn)單的Portlet參數(shù)配置。

          JSR168規(guī)范

          (先看一下在JSR168中提到的Portal page,可以了解一個(gè)Portal Page上大概有哪些element)

          JSR-168 (Enterprise Portlet Specification 1.0 Final Draft 發(fā)表于2003-09-03,是用于portlet級(jí)別開發(fā)的新Java portlet標(biāo)準(zhǔn)。依循于 JSR-168Portlet可以移植于其他的Portal Container上。 JSR-168規(guī)范的站點(diǎn): http://www.jcp.org/en/jsr/detail?id=168  

              JSR168Portal 的組成分為三部份 (1) Portal Server (2) Portlet Container (3) Portlet

          JSR168是Java 規(guī)范要求(Java Specification Request ,JSR)的縮寫,它為創(chuàng)建Portlet建立標(biāo)準(zhǔn)的API。很多重量級(jí)的Portal開發(fā)商和開源項(xiàng)目組參與了Java標(biāo)準(zhǔn)化組織(Java Community Process)創(chuàng)建JSR168標(biāo)準(zhǔn)的過程,并且很多Portal產(chǎn)品開始支持JSR 168。JSR168在2003年10月正式發(fā)布。最主要的Portal開發(fā)商已經(jīng)宣布計(jì)劃支持JSR 168標(biāo)準(zhǔn),查看JSR 168站點(diǎn)(http://www.jcp.org/en/jsr/detail?id=168 )可以得到目前為止JSR 168支持者的完整列表。

           按照J(rèn)ava標(biāo)準(zhǔn)化組織(Java Community Process)所述,JSR 168 portlet擁有一個(gè)適用于所有Portal客戶端的簡(jiǎn)單的、標(biāo)準(zhǔn)的API,支持多種類型的客戶端(多設(shè)備、多瀏覽器),支持本地化和國際化,允許門戶應(yīng)用程序的熱部署和重新部署,并且包含聲明性安全(與servlet和企業(yè)JavaBean規(guī)范中使用的機(jī)制相同)。

           現(xiàn)在開發(fā)商只需要支持一種Portlet集。結(jié)果,更多的ISV提供他們自己的通用的、開箱即用(out-of-the-box)的Portal集成構(gòu)件。這是值得客戶高興的時(shí)刻,因?yàn)殚_箱即用的應(yīng)用程序集成現(xiàn)在無需考慮選擇那個(gè)Portal開發(fā)商就可以使用。

             JSR 168意味著在Portal市場(chǎng)上,爭(zhēng)奪主導(dǎo)地位的優(yōu)勢(shì)不再是哪個(gè)開發(fā)商擁有最多數(shù)目ISV的開箱即用集成。相反,標(biāo)準(zhǔn)化通過使ISV支持他們自己的Porlet統(tǒng)一了這一領(lǐng)域。客戶的風(fēng)險(xiǎn)和成本降低,并且不再根據(jù)重建Portlet的的業(yè)務(wù)量來選擇門戶開發(fā)商。在選擇Portal開發(fā)商的時(shí)候,主要的決定性因素將是Portal產(chǎn)品與客戶企業(yè)體系結(jié)構(gòu)的適應(yīng)程度。

           對(duì)程序員簡(jiǎn)而言之,開發(fā)符合JSR168規(guī)范的Portlet將可以順利移植到符合該規(guī)范的不同Portal平臺(tái)上。



          PSML

          PSML的全名是Portal Structure Markup Language(門戶結(jié)構(gòu)標(biāo)記語言)。J2用PSML來定義Portal內(nèi)的各種resource,包括Page、Folder、Link、Security、Menus等等,有關(guān)J2的PSML詳細(xì)介紹見:

          http://portals.apache.org/jetspeed-2/guides/guide-psml.html。

          這里要特別提一下PSML Page。在J2中,一個(gè)PSML Page就代表一個(gè)Portal page,其根元素為<page>,里面指定了這個(gè)Portal page所包含的portlet及排列方式(ex: 2行或3行)、這個(gè)Portal page所使用的樣板(稍后會(huì)提到的layout)還有這個(gè)Portal page的外觀(稍后會(huì)提到的decoration)等等。

          另外一個(gè)要特別說明的是在PSML Page中所使用的<fragment>這個(gè)tag。fragment有portlet和layout二種,用type這個(gè)屬性來區(qū)別:<fragment type="portlet">代表一個(gè)portlet,<fragment type="layout">代表這個(gè)page所用的layout;然而不管是哪一種fragment,name屬性的值都應(yīng)該依照"portlet-app-id::portlet-id"的格式。

          事實(shí)上,layout fragment其實(shí)也是portlet??匆幌?/span>

          tomcat的webapps"jetspeed"WEB-INF"apps"里有一個(gè)jetspeed-layouts目錄,就是J2內(nèi)部的一個(gè)Portlet application。因此"jetspeed-layouts::VelocityTwoColumns"回對(duì)到這個(gè)目錄下portlet-id為VelocityTwoColumns的portlet??傊?,J2的layout也是portlet,如果再研究一下,其實(shí)這是個(gè)Velocity Bridge的portlet.

          layout

          J2中的layout指的是用來排列Portal page中各個(gè)portlet的樣板。默認(rèn)的情況下,J2用Velocity來實(shí)現(xiàn)layout。

          decoration 

          J2中的decoration是用來裝飾Portal page和portlet使其美觀,分為layout-decoration和portlet-decoration兩種。layout-decoration負(fù)責(zé)一整個(gè)Portal page(因此叫page-decoration),而portlet-decoration負(fù)責(zé)每一個(gè)Portlet fragment。默認(rèn)的情況下,J2用Velocity和CSS來實(shí)現(xiàn)decoration。當(dāng)J2在呈現(xiàn)一Portal page時(shí),會(huì)依照這個(gè)Portal page指定的layout來排列這個(gè)page上的各個(gè)portlet,并且使用這個(gè)page所指定的layout-decoration和portlet-decoration來美化這個(gè)page和所有的portlet。有關(guān)decoration的細(xì)節(jié)可參考http://portals.apache.org/jetspeed-2/guides/guide-decorators.html 。

          Aggregator

          在J2中,一個(gè)Portal page的request最后通常會(huì)傳給Aggregator,然后由Aggregator負(fù)責(zé)跟Portal page內(nèi)包含的所有portlet溝通并聚合各個(gè)portlet fragment以產(chǎn)生整個(gè)Portal page。從tomcat的webapps"jetspeed"WEB-INF"assembly"pipelines.xml),可以看到aggregatorValve這個(gè)bean被注入了org.apache.jetspeed.aggregator.PageAggregator這個(gè)Aggregator;再參考webapps"jetspeed"WEB-INF"assembly"aggregation.xml中,可已知道這個(gè)bean的類是org.apache.jetspeed.aggregator.impl.PageAggregatorImpl。

          來看一下這個(gè)PageAggregatorImpl的中用來產(chǎn)生Portal page的方法(部份省略修改):

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14

           public void build( RequestContext context ){

              //取得requested page

              ContentPage page=context.getPage();

            

              //取得 root fragment

              ContentFragment root = page.getRootContentFragment();

             

              //aggregate及render各Portlet,基本上render的結(jié)果都寫到context里

              aggregateAndRender(root, context, page);

              //將結(jié)果寫入response

              context.getResponse().getWriter().write(root.getRenderedContent());

             

          }



          首先要注意一下傳的是一個(gè)J2的RequestContext,基本上可以視為是用來存放這次request相關(guān)的一個(gè)context;此外,可以把ContentFragement視為portlet。而其中第6行取得root fragment,實(shí)際上就是取得前面所說的layout fragment,也就是"jetspeed-layouts::VelocityTwoColumns"這個(gè)portlet。

          接著再看一下第9行的aggregateAndRender()方法(部份省略修改):

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17

          protected void aggregateAndRender( ContentFragment f, RequestContext context, ContentPage page ){

              Iterator children = f.getContentFragments().iterator();

              while (children.hasNext()){

                  ContentFragment child = (ContentFragment) children.next();

                 

                  //遞歸

                  aggregateAndRender(child, context, page);

              }

                

               // 開始真正做render的動(dòng)作,基本上render的結(jié)果都寫到context里

               renderer.render(f, context); //renderer是org.apache.jetspeed.aggregator.impl.PortletRendererImpl

              

               //加上decoration

               addStyle(context, f.getDecorator(),ContentFragment.PORTLET);

                

          }

          由上面的code,可以了解到J2先把整個(gè)page上所有的portlet由外到內(nèi)串起來,再由內(nèi)到外一個(gè)一個(gè)做render的動(dòng)作,而每render完一個(gè)portlet,就加上對(duì)應(yīng)的decoration,直到做完整個(gè)page。

          在第12行中,render的動(dòng)作實(shí)際上是renderer通過Pluto呼叫portlet(實(shí)際上是ContentFragment被包成portlet window)的render方法。PortletRendererImpl.render()方法里使用了常見的Worker Thread和Observer樣式,以達(dá)到render多個(gè)portlet的功能。

          那如果想要新加外觀呢?最簡(jiǎn)單的方式,就是先參考J2的layout portlet寫自已的layout,然后加入decoration。講起來容易,不過layout可是不太容易寫的,因?yàn)闋砍兜降募夹g(shù)還蠻多,而且對(duì)J2也要有一定了解;但是如果能做出來,安裝就不會(huì)太麻煩。也許等以后J2紅起來以后,會(huì)有各式各樣的外觀可以玩吧。

          Pluto

          200310JSR168規(guī)范1.0正式公布后,Jakarta Apache就開始實(shí)施Pluto計(jì)劃(冥王星計(jì)劃),最終開發(fā)出該規(guī)范的一個(gè)參考實(shí)現(xiàn)(Reference Implementation),即PlutoPluto1.0.1-rc2版與200412月發(fā)布。
              Pluto實(shí)現(xiàn)基于 JSR168的一個(gè) Portlet Container,相當(dāng)于為開發(fā)者提供了一個(gè)運(yùn)行portlets的工作平臺(tái)。Pluto本身也提供了一個(gè)簡(jiǎn)單的Portal模塊,該模塊僅僅是為了滿足Portlet容器和JSR 168的需要而寫的,因而顯得非常簡(jiǎn)單,提供的實(shí)用的Portlet也非常少。從某種意義上說Pluto更像是一個(gè)Portlet Container,作為一個(gè)實(shí)用的Portal開發(fā)框架尚需要更強(qiáng)大的支持。但新版本的Pluto仍沒有推出。對(duì)于Pluto的應(yīng)用開發(fā),Apache更推薦使用Jetspeed項(xiàng)目框架。
             盡管Pluto作為一個(gè)完整的Portal應(yīng)用還非常欠缺。但不少有影響力的Portal項(xiàng)目使用Pluto作為Portlet Container。這些項(xiàng)目包括:Jetspeed 、Cocoon uPortal 、Jahia等。由此可見Pluto的重要性。從開發(fā)者和學(xué)習(xí)者的角度看,Pluto的意義還在于為開發(fā)者和學(xué)習(xí)者提供了一個(gè)深入了解Portlet Container的簡(jiǎn)潔的參考實(shí)例。

          eXo

          eXo(支持JSR168)基于JSFPortal實(shí)現(xiàn)。最新版本是200410月發(fā)布的1.0RC1版。
          主要優(yōu)點(diǎn)包括:
          1 AOPAspectJ)實(shí)現(xiàn)的內(nèi)容管理系統(tǒng),極大提高了內(nèi)容管理性能;
          2 基于Pico ContainerPortlet ContainerPico是一個(gè)著名的IoC3輕量級(jí)容器。同時(shí)也實(shí)現(xiàn)了上下文共享,二次開發(fā)的流程比較清晰;
          3 使用Struts框架技術(shù);
          4 提供工作流技術(shù)服務(wù)(Workflow service)。
          5 提供了很多交流工具,通過XML可以為結(jié)構(gòu)化的信息輕易地創(chuàng)建視圖;
               由上可見eXo采用了諸多先進(jìn)技術(shù),但存在不少缺點(diǎn)。主要缺點(diǎn):由于Portal Server本身的數(shù)據(jù)是使用xmldb來進(jìn)行處理,保存到數(shù)據(jù)庫的數(shù)據(jù)都是亂碼而且它所有默認(rèn)的平臺(tái)字符集都是ISO-8859_1。缺乏中文的充分支持,對(duì)于中文門戶的開發(fā)并沒有優(yōu)勢(shì);由于JSF是重量級(jí)的表現(xiàn)層框架,使得exo的二次開發(fā)工作量比較大;對(duì)于商業(yè)Portal應(yīng)用開發(fā)需要購買License。總體開發(fā)難度較大。

          Liferay

          Liferay (http://www.liferay.com ) 代表了完整的J2EE應(yīng)用,使用了Web、EJB以及JMS等技術(shù),特別是其前臺(tái)界面部分使用Struts 框架技術(shù),基于XML的portlet配置文件可以自由地動(dòng)態(tài)擴(kuò)展,使用了Web Services來支持一些遠(yuǎn)程信息的獲取,使用 Apahce Lucene實(shí)現(xiàn)全文檢索功能。  
           Liferay的缺點(diǎn)是它缺乏一個(gè)簡(jiǎn)單清晰可拓展的架構(gòu)設(shè)計(jì),整個(gè)架構(gòu)比較復(fù)雜且龐大;Struts1.1本身并不支持JSR168,所以Liferay在實(shí)現(xiàn)諸如上下文共享等問題上顯得十分笨重且沒有從根本上解決這些問題;portlet設(shè)計(jì)也顯得比較凌亂。此外,如果你的門戶系統(tǒng)準(zhǔn)備應(yīng)用于商業(yè)用途,你需要購買License?;谒M(jìn)行二次開發(fā)比較困難。

           Liferay(支持JSR168)代表了完整的J2EE應(yīng)用 , 2005年1月推出的Professional 3.2.0。它的主要優(yōu)點(diǎn)有:
                (1)使用第三放的開源項(xiàng)目,如Hibernate等。特別是前臺(tái)界面部分使用了Struts技術(shù);
                (2)支持包括中文在內(nèi)的多種語言;
                (3)支持較多的先進(jìn)技術(shù),如Web Services、EJB, JMS, SOAP, XML等;

          Jportal

          JPortal (http://jportal.sourceforge.net ) 是目前最為符合JSR-168 Spec的Portal實(shí)現(xiàn)。他使用了攔截器技術(shù)和 Dynamic Proxy來實(shí)現(xiàn)Portlet的可插入設(shè)計(jì)。他目前只是一個(gè)原型的實(shí)現(xiàn)并且之關(guān)注于實(shí)現(xiàn) Portal Container,并沒有過多的 Portlet實(shí)現(xiàn)和設(shè)計(jì)。 優(yōu)點(diǎn)在于其的架構(gòu)清晰,易于擴(kuò)展,但在Portal的工業(yè)強(qiáng)度上需求的差距是比較大的,沒有分布式的概念是他目前架構(gòu)的一個(gè)致命的地方。

          Jetspeed-2相關(guān)資源鏈接

          http://www.apache.org/dist/portals/jetspeed-2/

          http://wiki.apache.org/portals/Jetspeed2/DevelopersDocumentation

          API:

          http://portals.apache.org/jetspeed-2/multiproject/jetspeed-api/apidocs/index.html

          Spring Framework:      

          http://static.springframework.org/spring/docs/1.2.x/reference/introduction.html

          http://portals.apache.org/jetspeed-2/guides/guide-components.html

          http://portals.apache.org/jetspeed-2/

          http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/

          http://portals.apache.org/jetspeed-2/guides/guide-psml.html
          http://portals.apache.org/jetspeed-2/guides/guide-decorators.html

          http://portals.apache.org/jetspeed-2/guides/guide-portal-design.html http://portals.apache.org/jetspeed-2/guides/guide-jpt.html

          http://community.java.net/portlet/

          http://blogs.ittoolbox.com/km/portals/

          http://exo.sourceforge.net/

          http://jcp.org/en/jsr/detail?id=168

          http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-portlet.html

          http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-portlet2.html

          http://developers.sun.com/prodtech/portalserver/reference/techart/jsr168/

          http://jakarta.apache.org/pluto

          http://www.sentom.net/list.asp?id=53  ( JSR#168 Portlet 說明)
          http://www.jcp.org/en/jsr/detail?id=168
          http://jakarta.apache.org/pluto


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          我實(shí)話告訴你們,我可是身經(jīng)百戰(zhàn)了.bbs我見的多了,哪個(gè)版我沒灌過?你們要知道, 一塌糊 涂的triangle,PIC,SEX版,那比你們不知道厲害到哪里去了,我在那談笑風(fēng)聲.你 們有一好就是無論在哪個(gè)版,什么話題都灌,但是灌來灌去的問題,都too simple, sometimes naive!你 們懂不懂呀?啊?所以說灌水啊,關(guān)鍵是要提高自己的知識(shí)水平.你 們啊,不要總想著弄個(gè)大坑,然后灌上十大,再把我羞辱一番……你們啊,naive!你們這 樣灌是不行地!~那你問我支持 不支持灌水,我說支持,我常來這裡灌,你說支持不支持?
          主站蜘蛛池模板: 湟源县| 确山县| 麦盖提县| 松潘县| 舞阳县| 兴仁县| 灯塔市| 志丹县| 西和县| 太保市| 杂多县| 郎溪县| 齐河县| 兰溪市| 双柏县| 绥棱县| 句容市| 衡水市| 突泉县| 都安| 临城县| 綦江县| 绩溪县| 昌江| 太和县| 高平市| 华亭县| 依安县| 湟源县| 清水河县| 望谟县| 微博| 郓城县| 阜城县| 鄂托克前旗| 临洮县| 井陉县| 东阳市| 杨浦区| 明水县| 高尔夫|