假设你打算结合多种技术来构建一个企业级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文件里加入如下几行:
<filter> <filter-name>sitemesh</filter-name> <filter-class> com.opensymphony.module.sitemesh.filter.PageFilter </filter-class> <init-param> <param-name>debug.pagewriter</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<decorators defaultdir="/decorators"> <!— 给需要页边菜单的页面配置页边菜单修饰器 --> <decorator name="sidemenu" page="sidemenu.jsp"> <pattern>/home.jsp</pattern> </decorator> <!— 给需要页头和页脚的页面配置页头页脚修饰器 --> <decorator name="headerfooter" page="headerfooter.jsp"> <pattern>/help.jsp</pattern> </decorator> </decorators>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> <html> <head> <title> My Site - <decorator:title default="Welcome!" /> </title> <decorator:head /> </head> <body> <table> <tr> <td> <H1> SiteMesh Corporation <H1> </td> </tr> <tr> <td><decorator:body /></td> </tr> <tr> <td> SiteMesh copyright</td> </tr> </table> </body> </html>
<HTML> <HEAD> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> <TITLE>Help Page</TITLE> </HEAD> <BODY> Help Page </BODY> </HTML>
<?xml version="1.0" encoding="UTF-8"?> <sitemesh> <property name="decorators-file" value="/WEB-INF/decorators.xml"/> <excludes file="${decorators-file}"/> <page-parsers> <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" /> </page-parsers> <decorator-mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper"> <param name="property.1" value="meta.decorator" /> <param name="property.2" value="decorator" /> </mapper> <!-- Mapper for localization --> <mapper class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper"> <param name="match.en" value="en" /> <param name="match.zh" value="zh" /> </mapper> <!-- Mapper for browser compatibility --> <mapper class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"> <param name="match.MSIE" value="ie" /> <param name="match.Mozilla/" value="ns" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"> <param name="decorator" value="printable" /> <param name="parameter.name" value="printable" /> <param name="parameter.value" value="true" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper"> <param name="decorator.parameter" value="decorator" /> <param name="parameter.name" value="confirm" /> <param name="parameter.value" value="true" /> </mapper> <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"> <param name="config" value="${decorators-file}" /> </mapper> </decorator-mappers> </sitemesh>
<mapper class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper"> <param name="match.en" value="en" /> <param name="match.zh" value="zh" /> </mapper>
<mapper class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"> <param name="match.MSIE" value="ie" /> <param name="match.Mozilla/" value="ns" /> </mapper>
<mapper class= "com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"> <param name="decorator" value="printable" /> <param name="parameter.name" value="printable" /> <param name="parameter.value" value="true" /> </mapper>
<mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper"> <param name="property.1" value="meta.decorator" /> </mapper>
<mapper class= "com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper"> <param name="decorator.parameter" value="decorator" /> <param name="parameter.name" value="confirm" /> <param name="parameter.value" value="true" /> </mapper>
<servlet> <servlet-name>sitemesh-velocity</servlet-name> <servlet-class> com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet </servlet-class> </servlet> <!--Declare servlet for handling freemarker requests --> <servlet> <servlet-name>sitemesh-freemarker</servlet-name> <servlet-class> com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet </servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>ISO-8859-1</param-value> </init-param> </servlet> <!-- Velocity servlet should serve all requests with .vm extension--> <servlet-mapping> <servlet-name>sitemesh-velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> <!-- FreeMarker servlet should serve all requests with .dec extension--> <servlet-mapping> <servlet-name>sitemesh-freemarker</servlet-name> <url-pattern>*.dec</url-pattern> </servlet-mapping>
<html> <head> <title>My Site - $Advanced SiteMesh</title> ${head} </head> <body> <table border="1"> <tr> <td>SiteMesh Corporation</td> </tr> <tr> <td>${body}</td> </tr> <tr> <td>SiteMesh copyright</td> </tr> </table> </body> </html>
<html> <head> <title>My Site - $title</title> $head </head> <body> <table border="1"> <tr> <td> SiteMesh Header </td> </tr> <tr> <td> Sidemenu </td> <td> $body </td> </tr> <tr> <td> SiteMesh Footer </td> </tr> </table> </body> </html>