它不仅仅能处理动态的内容,如jsp,php,asp等产生的内容,它也能处理静态的内容,如htm的内容,使得它的内容也符合你的页面结构的要求。甚至于它能将HTML文件象include那样将该文件作为一个面板的形式嵌入到别的文件中去。
SiteMesh框架是OpenSymphony团队开发的一个非常优秀的页面装饰器框架,它通过对用户请求进行过滤,并对服务器向客户端响应也进行过滤,然后给原始页面加入一定的装饰(header,footer等),然后把结果返回给客户端。通过SiteMesh的页面装饰,可以提供更好的代码复用,所有的页面装饰效果耦合在目标页面中,无需再使用include指令来包含装饰效果,目标页与装饰页完全分离,如果所有页面使用相同的装饰器,可以是整个Web应用具有统一的风格。
其数据流如下:
它定义了一个过滤器,然后把页面都加上统一的头部和底部。
需要先在WEB-INF/lib下引入sitemesh的jar包:http://wiki.sitemesh.org/display/sitemesh/Download 。这里使用2.4版本。
过滤器定义:
在web.xml中
<filter> <filter-name>sitemesh</filter-name> <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
decorators.xml文件:
WEB-INF下新建decorators.xml文件:
<?xml version="1.0" encoding="utf-8"?> <decorators defaultdir="/WEB-INF/layouts/"> <!-- 此处用来定义不需要过滤的页面 --> <excludes> <pattern>/static/*</pattern> </excludes> <!-- 用来定义装饰器要过滤的页面 --> <decorator name="default" page="default.jsp"> <pattern>/*</pattern> </decorator> </decorators>
不用过滤/static/目录下的文件,然后指定了装饰器:/WEB-INF/layouts/default.jsp。
我用的是Spring MVC,目录结构大致:
default.jsp:
<%@ page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="sitemesh" uri="http://www.opensymphony.com/sitemesh/decorator" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="ctx" value="${pageContext.request.contextPath}" /> <!DOCTYPE html> <html> <head> <title>QuickStart示例:<sitemesh:title/></title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Cache-Control" content="no-store" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <link type="image/x-icon" href="${ctx}/static/images/favicon.ico" rel="shortcut icon"> <link href="${ctx}/sc/bootstrap/2.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" /> <link href="${ctx}/sc/jquery-validation/1.11.0/validate.css" type="text/css" rel="stylesheet" /> <link href="${ctx}/css/base/default.css" type="text/css" rel="stylesheet" /> <script src="${ctx}/sc/jquery/jquery-1.9.1.min.js" type="text/javascript"></script> <script src="${ctx}/sc/jquery-validation/1.11.0/jquery.validate.min.js" type="text/javascript"></script> <script src="${ctx}/sc/jquery-validation/1.11.0/messages_bs_zh.js" type="text/javascript"></script> <sitemesh:head/> </head> <body> <div class="container"> <%@ include file="/WEB-INF/layouts/header.jsp"%> <div id="content"> <sitemesh:body/> </div> <%@ include file="/WEB-INF/layouts/footer.jsp"%> </div> <script src="${ctx}/sc/bootstrap/2.3.0/js/bootstrap.min.js" type="text/javascript"></script> </body> </html>
首先引入了SiteMesh标签。
<sitemesh:title/> 会自动替换为被过滤页面的title。
<sitemesh:head/> 会把被过滤页面head里面的东西(除了title)放在这个地方。
<sitemesh:body/> 被过滤的页面body里面的内容放在这里。
在content的上下引入了header和footer。
我们在头部引入了js和css,就可以重用了。
使用:
使用的过程中,几乎感受不到SiteMesh的存在。例如下面的页面:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <!-- 第一个被装饰(目标)页面 --> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>被装饰(目标)页面title</title> <script type="text/javascript" src="/js/hello.js"></script> </head> <body> <h4>被装饰(目标)页面body标签内内容。</h4> <h3>使用SiteMesh的好处?</h3> <ul> <li>被装饰(目标)页面和装饰页面完全分离。</li> <li>做到真正的页面复用,一个装饰页面装饰多个被装饰(目标)页面。</li> <li>更容易实现统一的网站风格。</li> <li>还有。。。</li> </ul> </body> </html>
这就是一个普通的页面,但是被SiteMesh装饰之后,就会自动去掉<html> <body> <head>等元素,然后把相应的东西放在模板对应位置上。
我们来看一下,被SiteMesh装饰过的页面源代码:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
总结:
SiteMesh配置简单,使用灵活,几乎不会影响我们的正常开发,作为一个默默无闻的好帮手,非常推荐使用。
SiteMesh简单例子
接下来通过一个SiteMesh简单例子来了解SiteMesh的功能:
- 将sitemesh-2.3.jar放 到 [web-app]/WEB-INF/lib目录下;
- 在[web-app]/WEB-INF/新建一个decorators.xml文件,包含以下内容:
- <?xml version="1.0" encoding="utf-8"?>
- <decorators defaultdir="/decorators">
- <!-- 此处用来定义不需要过滤的页面 -->
- <excludes>
- </excludes>
- <!-- 用来定义装饰器要过滤的页面 -->
- <decorator name="main" page="main.jsp">
- <pattern>/*</pattern>
- </decorator>
- </decorators>
- <?xml version="1.0" encoding="utf-8"?>
- <decorators defaultdir="/decorators">
- <!-- 此处用来定义不需要过滤的页面 -->
- <excludes>
- </excludes>
- <!-- 用来定义装饰器要过滤的页面 -->
- <decorator name="main" page="main.jsp">
- <pattern>/*</pattern>
- </decorator>
- </decorators>
- 在[web-app]/WEB-INF/web.xml添加以下内容:
- <filter>
- <filter-name>sitemesh</filter-name>
- <filter-class>
- com.opensymphony.module.sitemesh.filter.PageFilter
- </filter-class>
- </filter>
- <filter-mapping>
- <filter-name>sitemesh</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <filter>
- <filter-name>sitemesh</filter-name>
- <filter-class>
- com.opensymphony.module.sitemesh.filter.PageFilter
- </filter-class>
- </filter>
- <filter-mapping>
- <filter-name>sitemesh</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- 在[web-app]下创建一个decorators文件夹,在该文件下再创建一个装饰页面main.jsp,包含以下内容:
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- 第一个装饰页面 -->
- <head>
- <!-- 从被装饰页面获取title标签内容,并设置默认值-->
- <title><decorator:title default="默认title"/></title>
- <!-- 从被装饰页面获取head标签内容 -->
- <decorator:head/>
- </head>
- <body>
- <h2>SiteMesh装饰header</h2>
- <hr />
- <!-- 从被装饰页面获取body标签内容 -->
- <decorator:body />
- <hr />
- <h2>SiteMesh装饰footer</h2>
- </body>
- </html>
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- 第一个装饰页面 -->
- <head>
- <!-- 从被装饰页面获取title标签内容,并设置默认值-->
- <title><decorator:title default="默认title"/></title>
- <!-- 从被装饰页面获取head标签内容 -->
- <decorator:head/>
- </head>
- <body>
- <h2>SiteMesh装饰header</h2>
- <hr />
- <!-- 从被装饰页面获取body标签内容 -->
- <decorator:body />
- <hr />
- <h2>SiteMesh装饰footer</h2>
- </body>
- </html>
- 在[web-app]下创建被装饰页面index.jsp,包含以下内容:
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- 第一个被装饰(目标)页面 -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>被装饰(目标)页面title</title>
- </head>
- <body>
- <h4>被装饰(目标)页面body标签内内容。</h4>
- <h3>使用SiteMesh的好处?</h3>
- <ul>
- <li>被装饰(目标)页面和装饰页面完全分离。</li>
- <li>做到真正的页面复用,一个装饰页面装饰多个被装饰(目标)页面。</li>
- <li>更容易实现统一的网站风格。</li>
- <li>还有。。。</li>
- </ul>
- </body>
- </html>
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- 第一个被装饰(目标)页面 -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>被装饰(目标)页面title</title>
- </head>
- <body>
- <h4>被装饰(目标)页面body标签内内容。</h4>
- <h3>使用SiteMesh的好处?</h3>
- <ul>
- <li>被装饰(目标)页面和装饰页面完全分离。</li>
- <li>做到真正的页面复用,一个装饰页面装饰多个被装饰(目标)页面。</li>
- <li>更容易实现统一的网站风格。</li>
- <li>还有。。。</li>
- </ul>
- </body>
- </html>