Jetspeed2.0最终release版本发布于2005年12月, 可以从以下网址下载源代码和捆绑tomcat的压缩文件: http://www.apache.org/dist/portals/jetspeed-2/ 。
与Jetspeed1.x比较,Jetspeed2.0 (以下简称J2)的架构发生了很大变化, J1.x使用了Turbine,在J2中Turbine不再使用, 而是使用了Spring Framework作为默认的组件框架,从官方的资料介绍看,J2架构支持将一种组件架构替换为别的组建架构如Pico,Spring仅仅是J2默认的Component Framework,从本节下文的叙述中可以看到替换的方式。
portlet 之间可以通过session等来进行交互。所以谈不上 “JSR 168没有定义portlet之间的事件模型”。 由于Jetspeed不是基于JSF的,所以它的门户上的链接是无状态的,也许独立的AJAX可以让它更容易被集成。
Jetspeed-2使用pluto作为Portlet 容器。
Jetspeed-2组件框架(Component Framework)的装配是通过JetspeedServlet(org.apache.jetspeed.engine.JetspeedServlet)进行配置和实现的,见下图:
JetspeedServlet在web.xml中配置,门户应用启动时即执行JetspeedServlet。JetspeedServlet中initializeComponentManager
方法为给定的组件框架装载assemply(见WEB-INF/assembly),initializeComponentManager将spring framework作为默认的组件框架。并装配WEB-INF/assembly下的xml文件来初始化spring引擎。然后组件框架来创建
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相关的类图:
从上面的分析说明Jetspeed2的基础组架构是基于Spring组件的可伸缩的架构,Jetspeed2还有什么其他新的特性?
l Jetspeed 2.0 的final release版本完全兼容Portlet规范1.0(JSR-168)。Jetspeed2.0是Java Portlet API的完整实现。
l 支持SSO(Single Sign-On)单点登录, 单点登录技术是一种认证和授权机制,它允许注册用户只需要在任一成员网站上登录一次,而后授权访问其他连接的分支网站,无需再进行登录。
l Jetspeed-Bridge使Jetspeed可以集成Struts,JSF,PHP,Perl,Velocity,WebWork开发的应用。可以将Struts Action、Velocity模板、Perl脚本、PHP脚本等以Portlet的形式展现,这对旧系统的移植将很有帮助。JetSpeed 2.0还实现了一组常用的示例Portlet,包括日历、书签等小工具。
l 可配置的管道请求处理器(Pipeline Request Processor)。管道可把一些访问的请求根据参数,分配给portlet的容器。
l JAAS数据库安全策略。
l Jetspeed支持AJAX XML API。
l portlet应用的自动部署。
l 基于LDAP及数据库实现的安全组件。为用户认证提供LDAP支持。
l 开发者可使用Jetspeed PSML语言装配portlets。
l 门户内容管理和导航:页面、菜单、文件夹、链接。
l 多线程的聚合引擎。
l 集成主流的数据库:Derby, MySQL, MS SQL, Oracle, Postgres, DB2
l 国际化支持
l 统计日志引擎。
l Portlet注册
l 使用Lucene对Portlet组件进行全文搜索。
l 用户注册功能
l 遗忘密码获取功能
l 丰富的登录和口令配置管理功能
l 基本页面定制
l 管理Portlet:
- 用户、角色、组、密码和Profile管理
- JSR168 用户属性编辑器
- Portlet应用和生命周期管理
- Profiler系统管理
- 统计报表
门户设计的特征:
l 可部署Jetspeed Portlet和页面皮肤(Decorators)CSS组件。
l 可配置的CSS页面外观(Layouts)。
l 很容易为皮肤和Layouts组件使用Velocity宏语言
引擎部分是Jetspeed-2,而Container是Pluto Portlet Container,Portlet就是自己写的Portlet;所以这张图正好对照JSR168中的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) 。
2、RequestContextComponent会针对这个 request建立一个
RequestContext(org.apache.jetspeed.JetspeedRequestContext),并且让这个request和新建的RequestContext能互相参照。
3、呼叫Engine(org.apache.jetspeed.JetspeedEngine)的service()方法,这个方法会把刚刚建立的RequestContext传入,这样后面的组件才能使用。
4、在service()方法中,Engine会依据request的目标URL来取得相对应的Pipeline(org.apache.jetspeed.pipelineJetspeedPipeline)来处理。Pipeline使用了chain of responsibility的pattern,是由一堆Valve(org.apache.jetspeed.pipeline.valve.Valve)串起來的。
5、各个Valve依序执行,其中某些Valve会和Container动作,某些Valve会负责产生要response的portal页面。在这个过程中,Continer会执行相关的Portlet,并将結果返回至Pipeline,也就是Valve chain中。
6、将产生的portal页面传回给user,流程結束。
由上面的介绍,应该可以体会到Pipeline在J2中是非常重要的,这里附上Pipeline的官方UML图做参考。
Jetspeed-2本身是Spring-based的架构,主要的Spring设定都在webapps"jetspeed"WEB-INF"assembly下。JetspeedServlet在init时会建立Spring容器并载入这些xml文件,而之前提到的ComponentManager就可以通过name或class在Spring容器中寻找需要的component。有关J2的component,请务必参考http://portals.apache.org/jetspeed-2/guides/guide-components.html及源代码。
看一下assembly目录中的pipelines.xml。这个XML是用来组合各个Pipeline和设定各Pipeline和其对应的URL。先看一下最后一段bean id="pipeline-map"的部份,在这边可以看到URL和其相对应的Pipeline。另外找到bean id="jetspeed-pipeline"这一段,可以看到这個Pipeline中Valve的组合,而这个Pipeline也是default的Pipeline;有兴趣的不妨参这个XML文件,把这个Pipeline中的Valve的原始代码找到翻一翻,大致了解一下每个Valve在做啥。
Jetspeed-2性能:
在jetspeed2中还使用了多线程异步处理,用以提高Performance. 但是事实上第一次运行的开销还是挺大的,比如一个Portal页面上有20个Portlet,那么Portlet Container就需要初始20个web application. 加载class总是很耗资源的. 目前没有十分好的方法。
J2使用JAAS的来处理security有关的问题。在j2捆绑的tomcat中,从bin同级别目录conf中查找Catalina"localhost"jetspeed.xml,打开这个文件可看到有关JAAS Realm及login的设定。
tomcat"conf" l及C:"tomcat"webapps"jetspeed"WEB-INF"web.xml看到有關及login的設定 :
<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三个概念。在J2中有user、role、group三种Principal。而Permission基本上有page、portlet,tab等等,当然也可以增加自定的Permission。至于Policy,J2并没有使用JAAS的policy,而是使用自带的RdbmsPolicy,也就是把Policy的信息存在资料库中;而通过适当的设置, J2也可以使用相关App Server的JAAS。
底下是官方的security组加的架构图:
在J2中,核心的部份就是"J2 Security Coarsed Services"里的4个Manager组件:UserManager,RoleManager,GroupManager,PermissionManager, J2的JAAS login module实际上是使用UserManager来进行authentication;UserManager通过OJB自数据库中取出user的信息例如UserPrincipal、Crendential等并进行authorization.
J2在security的部份也提供了SPI的设计供开发人员加入自定的认证方式,例如使用LDAP,参考底下官方的连接:
http://portals.apache.org/jetspeed-2/multiproject/jetspeed-security/ldap.html ,可以知道如何使用LDAP来进J2上的认证。
随着Portal一步步走向成熟其结构和功能也发生了较大变化,从混和型服务走向以系统框架为核心,应用程序与部署、开发完全分开的阶段,Portal相当与一个骨架一样可以接纳外部的这种技术架构开发的应用程序,使用Portals Bridges模式来连接不同的应用程序,可包括以下几种:
集成Struts MVC模式开发的应用程序;
集成WebWorks开发的应用程序;
集成JSF开发的应用程序;
集成Perl开发的应用程序;
集成PHP开发的应用程序;
Struts已经成为了用Java创建Web应用的一个最流行的框架工具,Struts所实现的MVC模式给Web应用带来了良好的层次划分,同时也提供了一系列的工具来简化Web应用的开发。
应用程序开发者无需关心Portal的规范,只要关心Struts本身的开发,这样大大降低了开发成本和开发人员的再培训。
主要实现类: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>
WebWork是一个源代码开放的Web应用框架,用于简化基于Web的应用开发。可使用WebWork和JavaServerPages(JSP)、Velocity来建立注册界面。通过Jetspeed2的Portals Bridges框架来实现和webwork的集成,主要实现类:
public class Webwork2Portlet extends GenericPortlet
JSF为广大基于JAVA的 Web应用用户界面的开发人员提供了标准的编程接口、丰富可扩展的UI组件库(一个核心的JSP标记库用来处理事件、执行验证以及其他非UI相关的操作和一个标准的HTML 标记库来表示 UI组件)、事件驱动模型等一套完整的Web应用框架,通过 JSF ,您可以在页面中轻松自如地使用 WEB 组件、捕获用户行为所产生的事件、执行验证、建立页面导航…,同时您会发现,当使用支持JSF的开发工具来开发 JSF 应用的时候,一切将会变得异常简单,就类似于我们现在开发VB或者PowerBuilder程序一样的简便,GUI方式拖放组件、修改组件属性、建立组件间关联以及编写事件侦听器等等,这样,一个并不是特别熟悉Java的Web应用开发人员也能够轻松地完成自己的任务了,这种易开发性对于J2EE而言无疑是太重要了。
Perl 就是 Practical Extraction and Reporting Language 的简称,是一种最广泛应用于语法分析和 World Wide Web 的编程语言。它起源于 awk、C、sh 和 sed 语言,然而,它的应用开发远比其他任何一种面向对象编程语言更加容易。
实现方法:
public class PerlPortlet extends GenericPortlet
直接通过HttpServletResponseWrapper来封装获取Response的字节流
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>
PHP是一个基于服务端来创建动态网站的脚本语言,您可以用PHP和HTML生成网站主页。当一个访问者打开主页时,服务端便执行PHP的命令并将执行结果发送至访问者的浏览器中,这类似于ASP和CoildFusion,然而PHP和他们不同之处在于PHP开放源码和跨越平台,PHP可以运行在WINDOWS NT和多种版本的UNIX上。它不需要任何预先处理而快速反馈结果,它也不需要mod_perl的调整来使您的服务器的内存映象减小。PHP消耗的资源较少,当PHP作为Apache Web服务器一部分时,运行代码不需要调用外部二进制程序,服务器不需要承担任何额外的负担。实现类:
public class PHPApplicationPortlet extends GenericPortlet
WSRP由OASIS(一个由开发电子商务标准的行业专家所组成的非赢利性社团)创建,它规定Porlet的远程渲染(rendering)。主要目的就是为网络服务提供视觉化和使用者面对面服务的主要构件。WSRP最重要的特性就是它具有随插随用(plug-and-play)的功能,可以让互联网门户或其他网络应用(如手机,PDA等)从网络不同的来源处将多样内容或是应用聚集起来。WSRP使获得原来极难实现的功能成为可能。例如,部署一次,但把它们传递到任何地方,将第三方的Portlet整合在一起,增强来自不同开发商的门户之间的互操作性。WSRP也为客户提供了一种构建联合门户的可行方法。联合门户由互操作的门户网络组成,由此,某一门户托管的资源可以被许多门户使用。采用联合门户有无数的好处,包括门户合理化和更少的IT管理的Web资产。
过去,一个Portlet只能被托管它的同一门户本地使用。而有了WSRP,则可以将一个Portlet从门户表面(“使用”)的Portlet交给物理上、逻辑上独立的基础设施托