使用一个东东,首先要了解它到底是什么?能完成什么样的功能?为什么要使用它?
官方这么说:
SiteMesh is a lightweight and flexible Java web application framework that applies the Gang of Four decorator pattern to allow a clean separation of content from presentation. Work with the simple content of your website and have the complex presentation code centrally applied (decorated) just before delivery to the client At the same time, SiteMesh has many advanced features and works with popular frameworks such as Spring and Struts.
SiteMesh应用Decorator模式,通过filter截取request和response,把页面组件head,content,banner结合为一个完整的视图。通常我们都是使用incluce标签在每个jsp页面中不断的包含各种header,stylesheet,scripts,footer,现在,在SiteMesh的帮助下,我们就不用那么麻烦了,如下图:
Download
目前SiteMesh的最新版本是2.4.2,可以到官方网站下载:http://wiki.sitemesh.org/display/sitemesh/Home
A simple example
截图:
1、引入需要的jar文件(sitemesh-2.3.jar)
2、配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <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> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
3、编写装饰器文件(decorators.xml)
<?xml version="1.0" encoding="UTF-8"?> <decorators defaultdir="/decorators"> <decorator name="main" page="main.jsp"> <pattern>*</pattern> </decorator> </decorators>
4、编写两个基本页面
main.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%> <html> <head> <title><decorator:title default="装饰器页面默认标题" /> </title> <decorator:head /> </head> <body> sitemesh的例子 <hr> <decorator:body /> <hr> http://www.cnblogs.com/shanshouchen/ </body> </html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>SiteMesh Test</title> </head> <body> <b>我只想说十个字,说完了</b> </body> </html>
5、部署并启动服务器,浏览效果如下
什么叫装饰器(Decorator)
为了建立可复用的web应用程序,一个通常的做法是建立一个分层系统,如同下面一个普通的web程序:
表示层(View):JSP、Servlets、velocity、freemark…
控制层(Controller):Struts、Webwork…
业务层(Business):主要业务逻辑
持久层:hibernate、iBATIS…
比较糟糕的是表示层的页面逻辑很难被复用,当你在每个页面中用数不尽的include类复用公共的header,stylesheet,footer的时候,一个问题出现了:大量重复的代码,每个页面都必须用copy来复用页面结构,而当你需要创意性的修改页面结构的时候,灾难就爱上了你
SiteMesh是通过filter截取request和response,并给原始的页面介入一定的装饰,然后把结果返回给客户端,并且被装饰的原始页面并不知道SiteMesh的装饰,这样也刚好达到的解耦的目的
如何配置SiteMesh的工作环境
除了要导入SiteMesh.jar,还有2个文件需要建立到WEB-INF/(默认是这样的,但不是必须要建立在这个目录)
sitemesh.xml(可选)
sitemesh.xml可以设置两种信息:Page Parsers和Decorator Mappers
Page Parsers:负责读取stream的数据到Page对象中以被SiteMesh解析和操作(不常用,默认即可)。
Decorator Mappers:不同的装饰器种类,常用两种,一种是通用的mapper,可以指定装饰器的配置文件,另一种可以打印的装饰器,可以允许你当用方式访问的时候给出原始页面一共打印
注:无特殊功能要求,此文件不用建立,默认就足够了:com/opensymphony/module/sitemesh/factory/sitemesh-default.xml
decorators.xml
<?xml version="1.0" encoding="UTF-8"?> <decorators defaultdir="/decorators"> <decorator name="main" page="main.jsp"> <pattern>*</pattern> </decorator> </decorators>
defaultdir:包含装饰器页面的目录
page:装饰器页面文件名
name:别名
Patterns:匹配路径,“*”表示所有的页面都需要被装饰
SiteMesh应用重点
在使用SiteMesh的过程中,最重要就是制作装饰器页面本身(也就是包含结构和规则的页面),然后把它们描述到decorators.xml中,我们来看一个简单的HelloWorld(你懂得!!!)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%> <html> <head> <title><decorator:title default="装饰器页面默认标题" /></title> <decorator:head /> </head> <body> sitemesh的例子 <hr> <decorator:body /> <hr> http://www.cnblogs.com/shanshouchen/ </body> </html>
我们在装饰器页面中只使用了3个标签:
<decorator:title default="装饰器页面默认标题" /> :把请求的原始页面的title内容插入到<title></title>中间。
<decorator:head /> :把请求的演示页面中head中的内容,插入到相应的位置,比如script,stylsheet…
<decorator:body /> :把请求的原始页面的body内的全部内容插入到相应位置
然后我们在decorator.xml中加入以下描述即可:
<?xml version="1.0" encoding="UTF-8"?> <decorators defaultdir="/decorators"> <decorator name="main" page="main.jsp"> <pattern>*</pattern> </decorator> </decorators>
这样一来,请求的所有页面都会被SiteMesh重新处理,并按照main.jsp的格式重新展示给客户端
关于SiteMesh更多标签的应用(想深入了解可以查看SiteMesh文档:)
SiteMesh使用文档:http://wiki.sitemesh.org/display/sitemesh/Tag+References
Decorator Tags(被用于建立装饰器页面) | Page Tags(被用于从原始内容页面访问装饰器) |
<decorator:head/> | <page:applyDecorator/> |
<decorator:title/> | <page:param/> |
<decorator:body /> | |
<decorator:getProperty property=""/> | |
<decorator:usePage id=""/> |
<decorator:head />
插入原始页面(被包装的页面)的head标签中的内容(不包含head标签本身)
<decorator:title [ default="..." ] />
插入原始页面(被包含的页面)的title标签中的内容,可以增加缺省值
例如:
装饰器页面中:<titile><decorator:title default=”缺省title”/>--这里是附加标题</title>
原始页面中:<title>SiteMesh Test</title>
返回的页面:<titile>SiteMesh Test--这里是附加标题</title>
如果原始页面中没有title,则返回的页面:<titile>缺省title--这里是附加标题</title>
<decorator:body />
插入原始页面(被包装的页面)的body标签中的内容
<decorator:getProperty property="..." [ default="..." ] [ writeEntireProperty="..." ]/>
在标签处插入原始页面(被包装的页面)的原有的标签的属性中的内容,还可以添加一个缺省值
官方例子如下
For example: The decorator: <body bgcolor="White"<decorator:getProperty property="body.onload" writeEntireProperty="true" />> The undecorated page: <body onload="document.someform.somefield.focus();"> The decorated page: <body bgcolor="White" onload="document.someform.somefield.focus();">writeEntireProperty=”true”会在插入内容之前加入一个空格。
<decorator:usePage id="..." />
跟jsp页面中的<jsp:useBean>标签一样,可以使用被包装为一个Page对象的页面
例如(获得标签):
<decorator:usePage id=”page”/> <%=page.getTitle()%>,效果与<decorator:title/>一样
再如:
<decorator:usePage id="myPage" /> <% if ( myPage.getIntProperty("rating") == 10 ) { %> <b>10 out of 10!</b> <% } %>
<page:applyDecorator name="..." [ page="..." title="..." ] > ..... </page:applyDecorator>
应用包装器到指定的页面上,一般用于被包装页面中主动应用包装器,我们来看一个例子:
包装器页面main.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%> <html> <head> <title><decorator:title default="装饰器页面默认标题" /></title> <decorator:head /> </head> <body> sitemesh的例子 <hr> <decorator:body /> <hr> http://www.cnblogs.com/shanshouchen/ </body> </html>decordators.xml配置
<?xml version="1.0" encoding="UTF-8"?> <decorators defaultdir="/decorators"> <decorator name="main" page="main.jsp"> <pattern>*</pattern> </decorator> </decorators>一个公共页面public/date.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%> <html> <head> <title>Date</title> </head> <body> <%=new java.util.Date()%> </body> </html>被包装页面index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%> <html> <head> <title>Test</title> </head> <body> <page:applyDecorator name="main" page="/public/date.jsp"> </page:applyDecorator> </body> </html>运行结果如下:
有运行结果可知,除了index.jsp会被默认的包装页面包装上header,footer外,index.jsp中海嵌套了date.jsp页面,并且date.jsp页面也会被main.jsp包装,
常见中文乱码问题
SiteMesh内部缺省字符集采用ISO-8859-1,直接使用会产生中文乱码,常用纠正方法:
在jsp页面设置<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>