站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题Advanced SiteMesh

Advanced SiteMesh

摘要: 原版在这里:http://www.onjava.com/pub/a/onjava/2004/09/22/sitemesh.html
假设你打算结合多种技术来构建一个企业级web站点。比如,你准备采用J2EE技术往你的web站点里添加新内容,而这个系统的其他部分是用CGI或者微软的IIS Server搭建的。

在这种情况下,怎样让你的应用系统从外观和感受(look and feel)上保持一致呢?一种办案就是采用J2EE技术全部重写,然后选用一种框架,比如Struts-Tiles,但这种办案的开发成本太高,不太现实。另一种可选方案是在你的应用系统的各个部分采用相同的Look and Feel。但这种方案会使维护站点变成噩梦,因为每当一个应用系统里面的Look and Feel需要改变的时候,你就需要让系统里的其他web应用保持同样的改变。

大多数用于解决这种商务需求的可用框架都有一个共同的缺点,他们不是平台相关就是框架相关。当你决定采用Tiles作为struts修饰器的时候,需要创建tiles定义文件tiles-defs.xml,然后在struts-config.xml里面声明forwards,引用这些tiles以修饰原始的JSP。

最简单的一种可能的解决方案是,全部采用纯html方式来生成你的web应用,每一个html页面都不需要知道自己将会被如何修饰,而是在外部采用某种机制来选择合适的修饰器修饰它们。这就是SiteMesh的功能。

SiteMesh是基于Java、J2EE和XML的开源框架,依赖于从Servlet 2.3版本里引入的新功能——过滤器(Filters)

安装和设置

按照以往的经验,学习任何新技术或新框架最好的办法,就是使用它来创建一个简单的应用程序。所以,我们将使用SiteMesh来创建一个简单的Struts应用程序。我们的应用程序包括三个页面:

•一个登录页面
•一个帮助页面,包括页头和页脚
•一个主页面,包括页头、页脚和页边菜单

下面是创建这个简单web应用程序的步骤:

1.SiteMesh基于过滤器,所以我们需要把SiteMesh过滤器通知给我们的web应用程序。在web.xml文件里加入如下几行:


sitemesh

com.opensymphony.module.sitemesh.filter.PageFilter


debug.pagewriter
true



sitemesh
/*


这几行是告诉web容器,所有对web应用的请求都会经由PageFilter“过滤”一下。PageFilter是sitemesh-2.1.jar里的一个类,你可以从http://www.opensymphony.com/sitemesh/download.html下载该jar包。

2.在WEB-INF目录下生成一个decorators.xml文件,内容如下:



/home.jsp


/help.jsp



decorators.xml文件用来在你的应用程序里定义修饰器(decorators)。在这个文件里,每个元素定义一个修饰器,name指定修饰器名,page指定修饰器所使用的JSP页面。子元素指定这些修饰器如何应用到实际的页面上去。

在我们的示例web应用里,定义了两个修饰器:追加页头和页脚的headerfooter.jsp和追加页边菜单的sidemenu.jsp。我们想修饰help页面追加页头和页脚,所以我们追加了一个/help.jsp路径子元素给headerfooter.jsp修饰器。

3.在WebContent/decorators目录下创建headerfooter.jsp:

<%@ taglib
uri="http://www.opensymphony.com/sitemesh/decorator"
prefix="decorator" %>

<head>
<br /> My Site - <br /> <decorator:title default="Welcome!" /><br />

</head>
<body>
<table>
<tr>
<td>


SiteMesh Corporation


</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td> SiteMesh copyright</td>
</tr>
</table>
</body>


一个SiteMesh修饰器其实就是一个使用SiteMesh自定义标签的JSP页面。在我们的web应用里,当用户请求help页面的时候,SiteMesh会拦截这个请求,然后再把它发送给web应用。而当应用返回响应的时候,SiteMesh会结合headerfooter.jsp文件解析这个响应,遇到就插入响应文件的<head>,遇到就插入响应文件的<body>。最后,被headerfooter.jsp修饰过的文件会被返回给客户端。

4.在WebContent目录下创建help.jsp:


<head>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
Help Page
</head>
<body>
Help Page
</body>


这是一个在web应用里很常见的help页面。

5.在浏览器里请求help.jsp页面,测试SiteMesh安装是否正常。浏览器将会返回一个包含页头和页脚的help页面。

SiteMesh架构

SiteMesh架构基于PageFilter——一个Servlet过滤器。容器接收到页面请求时,会把请求传递给PageFilter,PageFilter收集应用程序的响应细节,生成自定义的响应对象,然后连同请求一起传递给web应用程序。web应用程序把响应资源写入到自定义响应对象里,再返回给PageFilter。

1.解析阶段
当控制返回给PageFilter的时候,它会检查web应用生成响应的内容类型(content type),然后基于响应类型,生成不同的解析器来解析响应。比如,如果应用返回text/html类型的内容,SiteMesh会生成一个FastPageParser实例,并把web应用生成的页面传递给它。FastPageParser会解析这个页面,提取出这个页面的header、footer、title 等内容。

2.修饰阶段

解析结束后,SiteMesh开始修饰页面。这一阶段分成两部分:

a.决定如何修饰

SiteMesh有一个概念,叫做修饰器映射,实现这个概念的接口是DecoratorMapper(有init()和getDecorator()方法)。映射器在sitemesh.xml里声明。在sitemesh.xml文件里,每一个映射器都是它上一个映射器的父映射。当SiteMesh需要一个修饰器来修饰页面的时候,会在sitemesh.xml里查找映射器,生成找到的第一个映射器的实例并调用getDecorator()方法,在这个方法里尝试查找针对那个页面的修饰器。如果找到了就返回;否则,调用父映射器的getDecorator()方法,反复进行这个过程,直到找到正确的修饰器。

b.应用修饰

找到修饰器后,SiteMesh会把请求分发给它。修饰器JSP页面会访问在前阶段里解析出来的页面信息。使用各种SiteMesh自定义标签来提取页面信息不同的部分(比如header、footer和title)并把它们插入到输出文件合适的位置上去。

你可以在sitemesh.xml文件里自定义使用哪个页面解析器来解析指定的内容类型或者使用哪种修饰器映射方案,比如:

<?xml version="1.0" encoding="UTF-8"?>




class="com.opensymphony.module.sitemesh.parser.FastPageParser" />


class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">