在公司项目使用了 Appfuse ,其带有 SiteMesh 对于网页布局简化让我感觉很好用,本文旨在对对 Sitemesh的基本原理和在项目中使用 Sitemesh 的实现流程、使用技巧的介绍。 1. 基本原理SiteMesh 是以 Servlet 2.3API 为基础。它包含一个引擎,用来解析输出的网页或者网页片段,决定是否需要应用装饰器以及合并合适的装饰器。 SiteMesh 与应用内容无关,适用的内容格式包括 Html 、 JSP 、 Servlet 、 XSL ,甚至 CGI 。 2. 实现流程1) 当为 Servlet 容器指定一个 Http 请求时, SiteMesh 截取请求,使用一个 Servlet Filter ,然后捕捉 Html结果。 2) 然后这个 Html 被解析,并且任何相关的内容都被提取到一个 Page 对象中。 3) 询问 DecoratorMapper 来确定那一个装饰器需要被应用。 4) Servlet 向包含装饰器的 JSP 发送请求。 5 )装饰器生成带有从 page 对象中获得的内容的 Html 布局。
3. 在项目中使用 Sitemesh1. 将 sitemesh_[version].jar 包加到 WEB-INF/lib 下 2. 在 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 >
表示对系统中所有 url 请求均使用 sitemesh Filter 进行拦截。 3. 在 WEB-INF 下配置 sitemesh.xml 和 decorator.xml 配置文件。 Sitemesh.xml
< sitemesh > < property name ="decorators-file" value ="/WEB-INF/decorators.xml" /> < excludes file ="${decorators-file}" /> < page-parsers > < parser default ="true" class ="com.opensymphony.module.sitemesh.parser.HTMLPageParser" /> < parser content-type ="text/html" class ="com.opensymphony.module.sitemesh.parser.HTMLPageParser" /> < parser content-type ="text/html;charset=ISO-8859-1" class ="com.opensymphony.module.sitemesh.parser.HTMLPageParser" /> </ page-parsers > < decorator-mappers > <!-- for print --> < 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.ConfigDecoratorMapper" > < param name ="config" value ="${decorators-file}" /> </ mapper > </ decorator-mappers > </ sitemesh >
Decorator.xml
< decorators defaultdir ="/decorators" > < excludes > < pattern > /demos/* </ pattern > < pattern > /resources/* </ pattern > < pattern > /test* </ pattern > < pattern > /FCKeditor/* </ pattern > </ excludes > <!-- decorator for print(has parameter: printable=true) --> < decorator name ="printable" page ="decPrintable.jsp" /> < decorator name ="login" page ="decLogin.jsp" > < pattern > *login* </ pattern > <! —url 映射模式 -- > </ decorator > < decorator name ="default" page ="decDefault.jsp" > < pattern > /* </ pattern > <! — 缺省的装饰器 -- > </ decorator > </ decorators >
在 sitemesh.xml 中配置了两个 DecoratorMapper : PrintableDecoratorMapper 和 ConfigDecoratorMapper 。 PrintableDecoratorMapper 是供打印专用,在 url 后加上 printable=true 即会使用 decorator.xml 中指定的 printable 装饰器来对页面进行装饰,一般来说打印页面是只需要打印本页面的内容,其余的如头、脚、导航栏、左右菜单等是不需要打印的,通过装饰器可以轻松实现打印页面的过滤。 4. 创建一个装饰器 JSP 页面,我建议所有装饰器页面放到 decorators 目录,并且以 dec[ 功能 ].jsp 作为命名方式,如 decPrintable.jsp 、 decDefault.jsp 。 下面是一个装饰器的代码:
<! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd " > <%-- Include common set of tag library declarations for each layout --%> <% @ include file = " /common/taglibs.jsp " %> < html xmlns = " http://www./1999/xhtml " xml:lang = " en " > < head > < decorator:head /> </ head > < body < decorator:getProperty property = " body.id " writeEntireProperty = " true " /> < decorator:getProperty property = " body.onload " writeEntireProperty = " true " /> < decorator:getProperty property = " body.onunload " writeEntireProperty = " true " /> > <% @ include file = " /common/header.jsp " %> < h1 >< decorator:getProperty property = " page.heading " /></ h1 > <% @ include file = " /common/messages.jsp " %> < decorator:body /> < jsp:include page = " /common/footer.jsp " /> </ body > </ html >
注意其 <decorator:…> 标签,这些标签将被装饰的 page 页面的相应内容作为属性传入。 Page 页面的相关内容将放在 decorator 标签所指定的位置。 Title :标题 Head :头部,一般是公共的 js 、 css 及 meta 。 Body :被装饰的 page 的主体内容。 5 、 Sitemesh 通过在 sitemesh.xml 中配置 DecoratorMapper 配置映射器,通过在 decorator.xml 中配置装饰器文件及其匹配方式。当有页面需要输出到客户端时,将根据这些配置选择相应的装饰器来进行装饰,将装饰结果返回给客户界面。 4. 参考资料关于 Sitemesh 的 api 及详细使用说明可以参看其官方网站 http://www./sitemesh |
|