| 
 | 
 
| 
 
 通过使用SiteMesh插件,就可以在Struts2应用中使用SiteMesh装饰器页面来统一应用程序所有页面的显示风格。实际上,在Struts2中使用SiteMesh非常简单,因为Struts2将所有的值都保存在Stack Context或ValueStack中,因此在SiteMesh页面中使用Struts2的标准标签即可。[来源www.iocblog.net] 
 
1 安装SiteMesh插件 
与整合其他框架类似,Struts2与SiteMesh框架的整合也使用了插件方式进行管理,因此为了在Struts2中使用SiteMesh的页面装饰,必须安装SiteMesh插件。安装SiteMesh插件非常简单,将 Struts2下的struts2-sitemesh-plugin-2.0.6.jar文件复制到Web应用的根路径下,即可完成SiteMesh插件的安装。 
正如前面看到的,为了整合SiteMesh框架必须在web.xml文件中配置SiteMesh的核心过滤器,让该核心过滤器来过滤所有的用户请求。但我们知道,Struts2的所有值是保存在Stack Context或者ValueStack中的,默认情况是,某个过滤器一旦访问了该Stack Context或ValueStack后,里面对应的值将会被清除掉,如果先使用Struts2的FilterDispatcher来过滤用户请求,则 SiteMesh的过滤器将无法取得Stack Context或者ValueStack中的数据。 
为了解决整个问题,Struts2提供了 ActionContextCleanUp类。在Struts2的架构中,标准的过滤器链(filter-chain)一般以 ActionContextCleanUp 开始,后面跟着其他需要的过滤器,最后,由 FilterDispatcher来处理请求,FilterDispatcher通常是将请求传递给ActionMapper。 
ActionContextCleanUp 的一个重要作用是整合SiteMesh页面装饰器,它通知FilterDispatcher在正确的时间清楚ActionContext中的请求数据。 
注意:如果需要在SiteMesh的修饰器页面中访问ActionContext,ActionContextCleanUp 过滤器必须放在过滤器链的起点。 
ActionContextCleanUp过滤器用来与FilterDispatcher协同工作来整合SiteMesh,通常,我们会把把ActionContextUp过滤器排在第一位,似乎将FilterDispatcher排在第二位是较好解决方案。 
但问题是:ActionContextCleanUp过滤器只能保证在FilterDispatcher之前先不清除Stack Context和ValueStack中的值。如果将SiteMesh过滤器排在FilterDispatcher之后,这会导致SiteMesh过滤器无法访问到Stack Context和ValueStack中的值。 
因此,为了让SiteMesh过滤器和FilterDispatcher都可访问到Stack Context和ValueStack中的值,且FilterDispatcher可以在合适时机清除Stack Context和ValueStack中的值,应该使用如下的过滤器顺序: 
(1)ActionContextCleanUp过滤器。 
(2)SiteMesh核心过滤器。 
(3)FilterDispatcher过滤器。 
为此,在web.xml配置文件中使用如下三个过滤器,且过滤器的排列顺序也不能改变。 
<!-- 定义ActionContextCleanUp过滤器 --> 
<filter> 
 <filter-name>struts-cleanup</filter-name> 
 <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class> 
</filter> 
<!-- 定义SiteMesh的核心过滤器 --> 
<filter> 
 <filter-name>sitemesh</filter-name> 
 <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> 
</filter> 
<!-- 定义Struts2的核心过滤器 --> 
<filter> 
 <filter-name>struts</filter-name> 
 <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
</filter> 
<!-- 定义过滤器链 --> 
<!-- 排在第一位的过滤器是:ActionContextCleanUp过滤器。 --> 
<filter-mapping> 
 <filter-name>struts-cleanup</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping> 
<!-- 排在第二位的过滤器是:SiteMesh核心过滤器。 --> 
<filter-mapping> 
 <filter-name>sitemesh</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping>[来源www.iocblog.net] 
<!-- 排在第三位的过滤器是:FilterDispatcher过滤器。 --> 
<filter-mapping> 
 <filter-name>struts</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping> 
正如前面配置文件看到的,配置文件中定义了三个过滤器,这三个过滤器都会过滤所有的用户请求。这三个过滤器按顺序分别是:ActionContextCleanUp过滤器、SiteMesh核心过滤器和FilterDispatcher过滤器,这也正是前面分析的过滤器排列结果。 
 
2 在Struts2中使用SiteMesh 
一旦完成了SiteMesh插件的安装后,在Struts2应用中使用SiteMesh就变得非常简单了。 
安装了SiteMesh插件后,在Struts2中使用SiteMesh框架可以按如下步骤进行: 
(1)将SiteMesh的二进制JAR文件复制到Web应用的的WEB-INF/lib路径下。 
(2)定义装饰器页面。 
(3)通过decorators.xml文件来配置装饰器页面。 
下面以MyFaces+Struts2+Spring的整合应用为基础,并且使用装饰器来装饰该应用。 
实际上,这里所介绍的步骤可以为任何一个Web应用增加统一的页面装饰风格,为一个Web应用增加统一的页面装饰风格按如下步骤进行: 
(1)正如前面介绍的,将SiteMesh的二进制文件,也就是sitemesh-2.3.jar文件复制到Web应用的WEB-INF/lib路径下,再将 Struts2的SiteMesh插件文件,也就是struts2-sitemesh-plugin-2.0.6.jar文件复制到Web应用的WEB- INF/lib路径下。 
(2)修改web.xml文件,增加ActionContextCleanUp过滤器定义和SiteMesh的PageFilter过滤器定义,修改后的web.xml文件的代码如下: 
<?xml version="1.0" encoding="GBK"?> 
<web-app id="jsf" version="2.4"  
 xmlns="http://java.sun.com/xml/ns/j2ee"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
<!-- 定义ActionContextCleanUp过滤器 --> 
 <filter> 
  <filter-name>struts-cleanup</filter-name> 
  <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class> 
 </filter> 
<!-- 定义SiteMesh的核心过滤器 --> 
 <filter> 
  <filter-name>sitemesh</filter-name> 
  <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> 
 </filter> 
<!-- 定义Struts2的核心过滤器 --> 
     <filter> 
         <filter-name>struts</filter-name> 
         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
     </filter> 
<!-- 定义过滤器链 --> 
<!-- 排在第一位的过滤器是:ActionContextCleanUp过滤器。 --> 
     <filter-mapping> 
         <filter-name>struts-cleanup</filter-name> 
         <url-pattern>/*</url-pattern> 
     </filter-mapping> 
<!-- 排在第二位的过滤器是:SiteMesh核心过滤器。 --> 
     <filter-mapping> 
         <filter-name>sitemesh</filter-name> 
         <url-pattern>/*</url-pattern> 
     </filter-mapping> 
<!-- 排在第三位的过滤器是:FilterDispatcher过滤器。 --> 
     <filter-mapping> 
         <filter-name>struts</filter-name> 
         <url-pattern>/*</url-pattern> 
     </filter-mapping> 
 <!-- 定义一个Listener,该Listener在应用启动时创建Spring容器 --> 
    <listener> 
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
 <!-- 定义一个Listener,该Listener在应用启动时加载MyFaces的Context --> 
 <listener> 
        <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class> 
    </listener> 
<!-- 配置JSF的FacesServlet,让其在应用启动时加载 --> 
 <servlet> 
  <servlet-name>faces</servlet-name> 
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
  <load-on-startup>1</load-on-startup> 
 </servlet> 
<!-- 让FacesServlet拦截所有以*.action结尾的请求 --> 
 <servlet-mapping> 
  <servlet-name>faces</servlet-name> 
  <url-pattern>*.action</url-pattern> 
 </servlet-mapping> 
</web-app> 
经过上面的配置,已经增加了SiteMesh的支持。 
(3)定义装饰器页面。 
(4)增加装饰器定义文件,也就是在Web应用的WEB-INF/路径下下增加decorators.xml。 |   
 
 
 
 |