介绍
SiteMesh: OS(OpenSymphony)的SiteMesh是一个用来在JSP中实现页面布局和装饰(layout and decoration)的框架组件,能够帮助网站开发人员较容易实现页面中动态内容和静态装饰外观的分离。通常我们都是用include标签在每个jsp页面中来不断的包含各种header, stylesheet, scripts and footer,现在,在sitemesh的帮助下,我们可以开心的删掉他们了。
原理
sitemesh通过filter截取request和response,并给原始的页面加入一定的装饰(可能为header,footer…),然后把结果返回给客户端,并且被装饰的原始页面并不知道sitemesh的装饰,这也就达到了脱耦的目的。
使用
首先是web.xml 配置
<!-- sitemesh 过滤器 -->
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
其次还有两个文件
• sitemesh.xml (可选)
• decorators.xml
sitemesh.xml 可以设置2种信息:
Page Parsers :负责读取stream的数据到一个Page对象中以被SiteMesh解析和操作。(不太常用,默认即可)
Decorator Mappers : 不同的装饰器种类,我发现2种比较有用都列在下面。一种通用的mapper,可以指定装饰器的配置文件名,另一种可打印的装饰器,可以允许你当用http://localhost/aaa/a.html?printable=true方式访问时给出原始页面以供打印(免得把header,footer等的花哨的图片也搭上)
页面还可以通过使用ParameterDecoratorMapper在运行时指定要使用的修饰器。
使用ParameterDecoratorMapper,在sitemesh.xml里追加如下几行:
<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>
三个参数的意义分别如下:
•decorator.parameter
指定修饰器所使用的请求参数名。
•parameter.name
确定使用请求修饰器的确认参数名。
•parameter.value
确定使用请求修饰器的确认参数值。
PageDecoratorMapper
页面可以通过定义META属性来重载指定修饰自己的修饰器名
要使用这个映射器,需要在sitemesh.xml文件里加入如下几行:
<mapper
class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
<param name="property.1" value="meta.decorator" />
</mapper>
接下来就是
decorators.xml
<?xml version="1.0" encoding="UTF-8"?>
<decorators >
<decorator name="index-common" page="/rest/common/index-common">
<pattern>/rest/index</pattern>
</decorator>
<decorator name="website-decorater" page="/rest/common/website-decorater">
<pattern>/rest/product/gotoWebsiteDev</pattern>
</decorator>
<decorator name="purchaser" page="/rest/common/purchaser">
<pattern>/rest/purchaser/*</pattern>
</decorator>
<decorator name="purchaser-portal" page="/rest/common/purchaser-portal">
<pattern>/rest/purchaser/*</pattern>
</decorator>
<decorator name="no-menu" page="/rest/common/no-menu">
<pattern>/rest/*</pattern>
</decorator>
<decorator name="portal" page="/rest/common/portal">
<pattern>/*</pattern>
</decorator>
<excludes>
<pattern>*.js</pattern>
<pattern>*.css</pattern>
<pattern>*.gif</pattern>
<pattern>*.jpg</pattern>
<pattern><![CDATA[*&none_decorator*]]></pattern>
<pattern><![CDATA[*?none_decorator*]]></pattern>
<pattern><![CDATA[/rest/page/login*]]></pattern>
<pattern><![CDATA[/rest/user/login]]></pattern>
<pattern><![CDATA[/rest/page/401*]]></pattern>
<pattern><![CDATA[/rest/page/404*]]></pattern>
<pattern><![CDATA[/rest/page/500*]]></pattern>
<pattern><![CDATA[/rest/user/toFindPass]]></pattern>
</excludes>
</decorators>
decorator name="portal" page="/rest/common/portal">
<pattern>/*</pattern>
</decorator>
这种前面是名字,后面是请求地址。
@RequestMapping("common/no-menu")
public String noMenu(){
return "common/common-purchaser-no-menu";
}
定位到这个jsp装饰器界面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="decorator"
uri="http://www.opensymphony.com/sitemesh/decorator"%>
<%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page"%>
<%@ taglib uri="/tld/dict.tld" prefix="dict" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title><decorator:title/> XXXXXXXXXXXXXXXXXX</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/>
<meta name="renderer" content="webkit"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="<dict:domain name='domain.oss.html' />/plugins/reset/reset.css">
<link rel="stylesheet" href="<dict:domain name='domain.oss.html' />/styles/common/common.css">
<link rel="stylesheet" href="<dict:domain name='domain.oss.html' />/styles/common/common-purchaser-no-menu.css">
<script src="<dict:domain name='domain.oss.html' />/plugins/jquery/jquery.min.js"></script>
<decorator:head />
</head>
<body>
<input type="hidden" id="head-nav-id" value=" <c:url value="/rest/common/headNav"/>"/>
<input type="hidden" id="rootUrl" value="<%=request.getContextPath()%>">
<decorator:body />
<div class="copyright">
<div class="inner">
<div class="copyright-text">
<p></p>
<a target="_blank" href="XXXX">
<div class="img-records"></div>
<p class="records-words">XXXXXXXXXXXXXXXXXX</p>
</a>
</div>
</div>
</div>
</body>
</html>
<decorator:title default="装饰器页面..." /> //把请求的原始页面的title内容插入到<title></title>中间。
<decorator:body /> : 把请求的原始页面的body内的全部内容插入到相应位置。
然后我们在decorator.xml中加入以下描述即可:
<decorator name="main" page="main.jsp">
<pattern>*</pattern>
</decorator>
这样,请求的所有页面都会被重新处理
大概就是需要配置的全部内容了。