您的位置:首页 > 其它

SiteMesh简介

2012-04-03 18:02 465 查看
Web.xml中的写法:<!--Sitemeshfilter--> <filter> <filter-name>sitemeshFilter</filter-name> <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class> </filter> <filter-mapping> <filter-name>sitemeshFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
配置文件:<sitemesh> <mappingpath="/*"decorator="/decorator.html"/> </sitemesh>decorator文件的写法<?xmlversion="1.0"encoding="UTF-8"?> <decoratorsdefaultdir="/WEB-INF/layouts/"> <excludes> <pattern>/static/*</pattern> </excludes> <decoratorname="default"page="default.jsp"> <pattern>/*</pattern> </decorator> </decorators>excludes标签中的内容是不需要装饰的目录或文件。装饰模板网页文件的写法:<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Mini-Web示例:<sitemesh:title/></title> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/> <metahttp-equiv="Cache-Control"content="no-store"/> <metahttp-equiv="Pragma"content="no-cache"/> <metahttp-equiv="Expires"content="0"/> <sitemesh:head/> </head> <body> <divclass="container"> <%@includefile="/WEB-INF/layouts/header.jsp"%> <divid="content"class="span-24last"> <sitemesh:body/> </div> <%@includefile="/WEB-INF/layouts/footer.jsp"%> </div> </body> </html>填入到模板文件中网页:<%@pagecontentType="text/html;charset=GBK"%> <html> <head> <title>AgentTest</title> </head> <body> <p>本页只有一句,就是本句.</p> </body> </html>SiteMesh介绍:
简介:
sitemesh应用Decorator模式,用filter截取request和response,把页面组件head,content,banner结合为一个完整的视图。通常我们都是用include标签在每个jsp页面中来不断的包含各种header,stylesheet,scriptsandfooter,现在,在sitemesh的帮助下,我们可以开心的删掉他们了。如下图,你想轻松的达到复合视图模式,那末看完本文吧。
一、在WEB-INF/web.xml中copy以下filter的定义:<?xmlversion="1.0"encoding="GBK"?><web-appxmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"><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>二、copy所需sitemesh-2.3.jar到WEB-INF\lib下。(这里可以下载http://www.opensymphony.com/sitemesh/)三、建立WEB-INF/decorators.xml描述各装饰器页面。
<decoratorsdefaultdir="/decorators">
<decoratorname="main"page="main.jsp">
<pattern>*</pattern>
</decorator>
</decorators>

上面配置文件指定了装饰器页面所在的路径,并指定了一个名为main的装饰器,该装饰器默认装饰web应用根路径下的所有页面。四、建立装饰器页面/decorators/main.jsp
<%@pagecontentType="text/html;charset=GBK"%><%@tagliburi="http://www.opensymphony.com/sitemesh/decorator"prefix="decorator"%><html><head><title><decorator:titledefault="装饰器页面..."/></title><decorator:head/></head><body>sitemesh的例子<hr><decorator:body/><hr>chen56@msn.com</body></html>

五、建立一个的被装饰页面/index.jsp(内容页面)
<%@pagecontentType="text/html;charset=GBK"%>
<html>
<head>
<title>AgentTest</title>
</head>
<body>
<p>本页只有一句,就是本句.</p>
</body>
</html>

最后访问index.jsp,将生成如下页面:而且,所有的页面也会如同index.jsp一样,被sitemesh的filter使用装饰模式修改成如上图般模样,却不用再使用include标签。
装饰器decorator概念
为了建立可复用的web应用程序,一个通用的方法是建立一个分层系统,如同下面一个普通的web应用:前端:JSP和Servlets,或jakarta的velocity。。。
控制层框架Controller:(Struts/Webwork)
业务逻辑Business:主要业务逻辑
持久化框架:hibernate/jdo可糟糕的是前端的页面逻辑很难被复用,当你在每一个页面中用数之不尽的include来复用公共的header,stylesheet,scripts,footer时,一个问题出现了-重复的代码,每个页面必须用copy来复用页面结构,而当你需要创意性的改变页面结构时,灾难就爱上了你。sitemesh通过filter截取request和response,并给原始的页面加入一定的装饰(可能为header,footer...),然后把结果返回给客户端,并且被装饰的原始页面并不知道sitemesh的装饰,这也就达到了脱耦的目的。据说即将新出台的Portlet规范会帮助我们标准的实现比这些更多更cool的想法,但可怜的我还不懂它到底是一个什末东东,有兴趣的人可以研究jetspeed,或JSR(JavaSpecificationRequest)168,但我想sitemesh如此简单,我们不妨先用着。 
让我们看看怎样配置环境
除了要copy到WEB-INF/lib中的sitemesh.jar外,还有2个文件要建立到WEB-INF/:sitemesh.xml(可选)
decorators.xml

sitemesh.xml可以设置2种信息:

PageParsers:负责读取stream的数据到一个Page对象中以被SiteMesh解析和操作。(不太常用,默认即可)DecoratorMappers:不同的装饰器种类,我发现2种比较有用都列在下面。一种通用的mapper,可以指定装饰器的配置文件名,另一种可打印的装饰器,可以允许你当用http://localhost/aaa/a.html?printable=true方式访问时给出原始页面以供打印(免得把header,footer等的花哨的图片也搭上)(但一般不用建立它,默认设置足够了:com/opensymphony/module/sitemesh/factory/sitemesh-default.xml):范例:
<sitemesh><page-parsers><parserdefault="true"class="com.opensymphony.module.sitemesh.parser.DefaultPageParser"/><parsercontent-type="text/html"class="com.opensymphony.module.sitemesh.parser.FastPageParser"/><parsercontent-type="text/html;charset=ISO-8859-1"class="com.opensymphony.module.sitemesh.parser.FastPageParser"/></page-parsers><decorator-mappers><mapperclass="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"><paramname="config"value="/WEB-INF/decorators.xml"/></mapper>
<mapperclass="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"><paramname="decorator"value="printable"/><paramname="parameter.name"value="printable"/><paramname="parameter.value"value="true"/></mapper>
</decorator-mappers></sitemesh>
decorators.xml:定义构成复合视图的所有页面构件的描述(主要结构页面,header,footer...),如下例:
<decoratorsdefaultdir="/decorators"><decoratorname="main"page="main.jsp"><pattern>*</pattern></decorator><decoratorname="printable"page="printable.jsp"role="customer"webapp="aaa"/></decorators>
defaultdir:包含装饰器页面的目录
page:页面文件名
name:别名
role:角色,用于安全
webapp:可以另外指定此文件存放目录
Patterns:匹配的路径,可以用*,那些被访问的页面需要被装饰。 
最重要的是写出装饰器本身(也就是那些要复用页面,和结构页面)。
其实,重要的工作就是制作装饰器页面本身(也就是包含结构和规则的页面),然后把他们描述到decorators.xml中。
让我们来先看一看最简单的用法:其实最常用也最简单的用法就是我们的hello例子,面对如此众多的技术,我想只要达到功能点到为止即可,没必要去研究太深(除非您有更深的需求)。
<%@pagecontentType="text/html;charset=GBK"%>
<%@tagliburi="http://www.opensymphony.com/sitemesh/decorator"prefix="decorator"%>
<html>
<head>
<title><decorator:titledefault="装饰器页面..."/></title>
<decorator:head/>
</head>
<body>
sitemesh的例子<hr>
<decorator:body/>
<hr>chen56@msn.com
</body>
</html>

我们在装饰器页面只用了2个标签:<decorator:titledefault="装饰器页面..."/>:把请求的原始页面的title内容插入到<title></title>中间。<decorator:body/>:把请求的原始页面的body内的全部内容插入到相应位置。然后我们在decorator.xml中加入以下描述即可:<decoratorname="main"page="main.jsp"><pattern>*</pattern></decorator>这样,请求的所有页面都会被重新处理,并按照main.jsp的格式重新展现在你面前。 
让我们看看更多的用法。(抄袭sitemesh文档)
以下列着全部标签:
DecoratorTagsPageTags
被用于建立装饰器页面.被用于从原始内容页面访问装饰器.
<decorator:head/>
<decorator:body/>
<decorator:title/>
<decorator:getProperty/>
<decorator:usePage/>
<page:applyDecorator/>
<page:param
<decorator:head/>插入原始页面(被包装页面)的head标签中的内容(不包括head标签本身)。<decorator:body/>
插入原始页面(被包装页面)的body标签中的内容。<decorator:title[default="..."]/>插入原始页面(被包装页面)的title标签中的内容,还可以添加一个缺省值。例:/decorator/main.jsp中(装饰器页面):<title><decorator:titledefault="却省title-hello"/>
-附加标题</title>/aaa.jsp中(原始页面):<title>aaa页面</title>访问/aaa.jsp的结果:<title>aaa页面
-附加标题</title><decorator:getPropertyproperty="..."[default="..."][writeEntireProperty="..."]/>在标签处插入原始页面(被包装页面)的原有的标签的属性中的内容,还可以添加一个缺省值。sitemesh文档中的例子很好理解:Thedecorator:
<bodybgcolor="white"<decorator:getPropertyproperty="body.onload"writeEntireProperty="true"/>>
Theundecoratedpage:
<bodyonload="document.someform.somefield.focus();">
Thedecoratedpage:
<bodybgcolor="white"onload="document.someform.somefield.focus();">
注意,
writeEntireProperty="true"会在插入内容前加入一个空格。
<decorator:usePageid="..."/>象jsp页面中的<jsp:useBean>标签一样,可以使用被包装为一个Page对象的页面。(懒的用)例:可用<decorator:usePageid="page"/><%=
page.getTitle()%>达到<decorator:title/>的访问结果。
<page:applyDecoratorname="..."[page="..."title="..."]><page:paramname="...">...</page:param><page:paramname="...">...</page:param></page:applyDecorator>应用包装器到指定的页面上,一般用于被包装页面中主动应用包装器。这个标签有点不好理解,我们来看一个例子:包装器页面/decorators/panel.jsp:<p><decorator:title/></p>...<p><decorator:body/></p>并且在decorators.xml中有<decoratorname="panel"page="panel.jsp"/>一个公共页面,即将被panel包装:/public/date.jsp:...<%=newjava.util.Date()%>...<decorator:getPropertyproperty="myEmail"/>被包装页面/page.jsp:<title>page的应用</title>.....<page:applyDecoratorname="panel"page="/_public/date.jsp"><page:paramname="myEmail">chen_p@neusoft.com</page:param></page:applyDecorator>最后会是什末结果呢?除了/page.jsp会被默认的包装页面包装上header,footer外,page.jsp页面中还内嵌了date.jsp页面,并且此date.jsp页面还会被panel.jsp包装为一个title加body的有2段的页面,第1段是date.jsp的title,第2段是date.jsp的body内容。另外,page:applyDecorator中包含的page:param标签所声明的属性值还可以在包装页面中用decorator:getProperty标签访问到。
可打印的界面装饰
前面说过有1种可打印的装饰器,可以允许你当用http://localhost/aaa/a.html?printable=true方式访问时,应用其他的装饰器(自己指定),给出原始页面以供打印(免得把header,footer等的花哨的图片也搭上)。
让我们来看一看怎样实现他:1.首先在WEB-INFO/sitemesh.xml中设置:<mapperclass="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"><paramname="decorator"value="printable"/><paramname="parameter.name"value="printable"/><paramname="parameter.value"value="true"/></mapper>这样就可以通过?printable=true来使用名为printable的装饰器,而不是用原来的装饰器。2.在WEB-INFO/decorators.xml中定义相应的printable装饰器<decoratorname="printable"page="printable.jsp"/>3.最后编写printable装饰器/decorators/printable.jsp
<%@tagliburi="sitemesh-decorator"prefix="decorator"%><html><head><title><decorator:title/></title><decorator:head/></head><body><h1><decorator:title/></h1><palign="right"><i>(printableversion)</i></p><decorator:body/></body></html>
这样就可以让一个原始页面通过?printable=true开关来切换不同的装饰器页面。 
中文问题
由于sitemesh内部所使用的缺省字符集为iso-8859-1,直接使用会产生乱码,我们可以通过以下方法纠正之:方法1:可以在您所用的applicationserver的配置文件中找一找,有没有设置encoding或
charset的项目,然后设成gbk或gb2312即可

方法2:这也是我们一直使用的方法。1.在每一个jsp页里设置:<%@pagecontentType="text/html;charset=gbk"%>来告诉server你所要求的字符集。2.在每个jsp页的head中定义:<METAHTTP-EQUIV="content-type"CONTENT="text/html;charset=gbk">来告诉浏览器你所用的字符集。
总结:使用sitemesh最通常的途径:
1.配置好环境,2.在WEB-INFO/decroators.xml中描述你将建立的包装器。3.开发在decroators.xml中描述的包装器,最好存放在/_decorators目录下4.ok,可以看看辛勤的成果了:)
转载自:http://www.blogjava.net/shiwenfeng/archive/2009/10/27/299925.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: