由于信息太多,这里只能选取重要的来解释。首先,请注意名为 jetspeed的servlet,这就是前面一个小节里提到的入口servlet,它同时也是Portal runtime的入口,它被映射到几乎所有的URL Pattern。当来自客户端的Http请求满足这些Pattern时,jetspeed servlet将会触发如下图所示的处理流程:
图六 Jetspeed runtime execution process
JetspeedServlet首先会通过RequestContextComponent为当前Http Request创建RequestContext实例,然后在这个context下调用engine的service方法。然后就会进入Pipeline 的处理过程。
Pipeline
Jetspeed Pipeline实际上就是设计模式中常见的Chain of Responsibility模式的具体实现,其设计概念类似Servlet Filter,一个封装了HttpServletRequest和HttpServletResponse Object的Context在Pipeline中传递,每个valve都根据自己的需要从HttpServletRequest 对象中获取信息并将处理的结果写入context或HttpServletResponse对象,以传递给后面的valve使用。
这些Valve的定义和排序都是通过Spring Bean来配置的,定义文件为pipelines.xml,下面为该文件片断截取:
<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的一个Pipeline,第三行定义了这些Pipeline对应的URL Pattern。门户开发者可以很容易的定义自己特有的Pipeline Valve(只需要实现org.apache.jetspeed.pipeline.valve.Valve接口,并在这个xml文件中定义它),或者改变现有Pipeline中valve执行顺序,甚至创建新的Pipeline,并把它映射到某个URL Pattern上。但这里需要注意的是新URL Pattern映射不能跟现有的重复,这是因为映射是通过Map数据结构实现。让我们再把注意力返回到图六,接下来的Container处理由一个竖线分隔,这是由于在Pipeline的aggregatorValve发生了cross context dispatch。需要注意的是Valve的实现类并不是Thread Safe的,开发者必须自己管理共享变量,最好就是不要定义对象成员变量,全部使用方法内部变量。