﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-j2ee绿洲-文章分类-SiteMesh</title><link>http://www.blogjava.net/livery/category/23473.html</link><description>找到属于自己的一片天空</description><language>zh-cn</language><lastBuildDate>Thu, 28 Jun 2007 23:52:47 GMT</lastBuildDate><pubDate>Thu, 28 Jun 2007 23:52:47 GMT</pubDate><ttl>60</ttl><item><title>SiteMesh初探</title><link>http://www.blogjava.net/livery/articles/125556.html</link><dc:creator>心情经纬</dc:creator><author>心情经纬</author><pubDate>Thu, 21 Jun 2007 06:15:00 GMT</pubDate><guid>http://www.blogjava.net/livery/articles/125556.html</guid><wfw:comment>http://www.blogjava.net/livery/comments/125556.html</wfw:comment><comments>http://www.blogjava.net/livery/articles/125556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/livery/comments/commentRss/125556.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/livery/services/trackbacks/125556.html</trackback:ping><description><![CDATA[<p><span class=nobr><a href="http://www.opensymphony.com/sitemesh" rel=nofollow><u><font color=#800080>SiteMesh<sup><img class=rendericon height=7 alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width=7 align=absMiddle border=0></sup></font></u></a></span>是一个Web页面布局修饰框架, 用于构建包含大量页面, 需要一致的外观样式(look/fell), 导航和布局机制的大型网站.</p>
<p>在WebWork中集成SiteMesh相当容易: 实际上什么也不用做. WebWork把全部值栈数据都保存在请求attribute中, 这意味着如果想显示值栈(或ActionContext)中的数据, 只需使用WebWork附带的标准标签库, 就这么简单!</p>
<h2><a name=SiteMesh-ActionContextCleanUp></a>ActionContextCleanUp</h2>
<p>在WebWork的<a title=Architecture href="http://wiki.javascud.org/display/ww2cndoc/Architecture"><u><font color=#0000ff>架构</font></u></a>中, 标准的过滤器链(filter-chain)一般以 <strong>ActionContextCleanUp</strong> 开始, 后面跟着其他需要的过滤器. 最后, 由 <strong>FilterDispatcher</strong> 处理请求, 通常是将请求传递给ActionMapper. <strong>ActionContextCleanUp</strong> 的首要用途是为集成SiteMesh服务的. 他会通知FilterDispatcher在正确的时间清除请求. 否则, ActionContext将在SiteMesh修饰器访问数据之前被清除.</p>
<table class=warningMacro cellSpacing=8 cellPadding=5 width="85%" align=center border=0>
    <colgroup>
    <col width=24>
    <col></colgroup>
    <tbody>
        <tr>
            <td vAlign=top><img height=16 alt="" src="http://wiki.javascud.org/images/icons/emoticons/forbidden.gif" width=16 align=absMiddle border=0></td>
            <td><strong class=strong>警告</strong><br><em>如果</em>需要在修饰器中访问ActionContext, <strong>ActionContextCleanUp</strong> 过滤器<em>必须</em>放在过滤器链的起点. </td>
        </tr>
    </tbody>
</table>
<p>更多信息参见ActionContextCleanUp的JavaDoc文档:</p>
<p>该过滤器用来与FilterDispatcher协同工作以便于集成SiteMesh. 通常, 排列过滤器并保证SiteMesh排在第一位, 而让FilterDispatcher排在第二位看起来是最佳方案. 然而, 你可能希望在SiteMesh修饰器中使用WebWork的特性, 包括value stack, 但由于FilterDispatcher将清除ActionContext, 因此修饰器就访问不到想要的数据了. </p>
<p>通过添加本过滤器, FilterDispatcher会知道先不执行清除而是将清除推迟到本过滤器中执行, 修改后的顺序如下: </p>
<ul>
    <li>本过滤器
    <li>SiteMesh
    <li>FilterDispatcher </li>
</ul>
<p>(摘自snippet:id=description|javadoc=true|url=com.opensymphony.webwork.dispatcher.ActionContextCleanUp)</p>
<h2><a name=SiteMesh-VelocityandFreeMarkerDecorators></a>Velocity and FreeMarker Decorators</h2>
<p>WebWork提供了SiteMesh的PageFilter的一个扩展版本的过滤器用于协助与<a title=Velocity href="http://wiki.javascud.org/display/ww2cndoc/Velocity"><u><font color=#0000ff>Velocity</font></u></a>和<a title=FreeMarker href="http://wiki.javascud.org/display/ww2cndoc/FreeMarker"><u><font color=#0000ff>FreeMarker</font></u></a>的集成. 强烈推荐使用这个过滤器来取代SiteMesh提供的过滤器, 因为当你使用自己喜欢的模版语言创建视图时, 也能够使用标准的变量和<a title=Tags href="http://wiki.javascud.org/display/ww2cndoc/Tags"><u><font color=#0000ff>标签</font></u></a>.</p>
<h3><a name=SiteMesh-Velocity></a>Velocity</h3>
<p>如果你要使用Velocity作为SiteMesh修饰器, 推荐使用VelocityPageFilter. 这是SiteMesh的PageFilter的一个扩展版本, 应该定义在web.xml中, 位于 <strong>ActionContextCleanUp</strong> 和 <strong>FilterDispatcher</strong> 之间. 这样Velocity修饰器就可以使用$stack和$request来访问WebWork的变量.</p>
<table cellSpacing=0 cellPadding=0 width="100%" bgColor=#ffffe0 border=0>
    <tbody>
        <tr>
            <td>
            <div stlye="font-size:8px; text-align:center;">
            <center>Content pulled from external source. Click <a href="http://wiki.javascud.org/plugins/snippet/clearCache.action?id=example.velocity.filter.chain&amp;url=https%3A%2F%2Fwebwork.dev.java.net%2Fsource%2Fbrowse%2F*checkout*%2Fwebwork%2Fwebapps%2Fshowcase%2Fsrc%2Fwebapp%2FWEB-INF%2Fweb.xml%3Fcontent-type%3Dtext%252Fplain"><u><font color=#800080>here</font></u></a> to refresh.</center></div>
            </td>
        </tr>
        <tr>
            <td>
            <div class=code>
            <div class=codeContent>
            <pre class=code-xml><span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork-cleanup<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.dispatcher.ActionContextCleanUp<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>sitemesh<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.sitemesh.VelocityPageFilter<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.dispatcher.FilterDispatcher<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork-cleanup<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>sitemesh<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span></pre>
            </div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<h3><a name=SiteMesh-FreeMarker></a>FreeMarker </h3>
<p>如果你要使用FreeMarker作为SiteMesh修饰器, 推荐使用FreeMarkerPageFilter. 这是SiteMesh的PageFilter的一个扩展版本, 应该定义在web.xml中, 位于 <strong>ActionContextCleanUp</strong> 和 <strong>FilterDispatcher</strong> 之间. 这样FreeMarker修饰器就可以使用${stack}和${request}.来访问WebWork的变量.</p>
<table cellSpacing=0 cellPadding=0 width="100%" bgColor=#ffffe0 border=0>
    <tbody>
        <tr>
            <td>
            <div stlye="font-size:8px; text-align:center;">
            <center>Content pulled from external source. Click <a href="http://wiki.javascud.org/plugins/snippet/clearCache.action?id=example.freemarker.filter.chain&amp;url=https%3A%2F%2Fwebwork.dev.java.net%2Fsource%2Fbrowse%2F*checkout*%2Fwebwork%2Fwebapps%2Fshowcase%2Fsrc%2Fwebapp%2FWEB-INF%2Fweb.xml%3Fcontent-type%3Dtext%252Fplain"><u><font color=#0000ff>here</font></u></a> to refresh.</center></div>
            </td>
        </tr>
        <tr>
            <td>
            <div class=code>
            <div class=codeContent>
            <pre class=code-xml><span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork-cleanup<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.dispatcher.ActionContextCleanUp<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>sitemesh<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.sitemesh.FreeMarkerPageFilter<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;filter-class&gt;</span>com.opensymphony.webwork.dispatcher.FilterDispatcher<span class=code-tag>&lt;/filter-class&gt;</span>
            <span class=code-tag>&lt;/filter&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork-cleanup<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>sitemesh<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-mapping&gt;</span>
            <span class=code-tag>&lt;filter-name&gt;</span>webwork<span class=code-tag>&lt;/filter-name&gt;</span>
            <span class=code-tag>&lt;url-pattern&gt;</span>/*<span class=code-tag>&lt;/url-pattern&gt;</span>
            <span class=code-tag>&lt;/filter-mapping&gt;</span></pre>
            </div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/livery/aggbug/125556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/livery/" target="_blank">心情经纬</a> 2007-06-21 14:15 <a href="http://www.blogjava.net/livery/articles/125556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Advanced SiteMesh</title><link>http://www.blogjava.net/livery/articles/125299.html</link><dc:creator>心情经纬</dc:creator><author>心情经纬</author><pubDate>Wed, 20 Jun 2007 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/livery/articles/125299.html</guid><wfw:comment>http://www.blogjava.net/livery/comments/125299.html</wfw:comment><comments>http://www.blogjava.net/livery/articles/125299.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/livery/comments/commentRss/125299.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/livery/services/trackbacks/125299.html</trackback:ping><description><![CDATA[假设你打算结合多种技术来构建一个企业级web站点。比如，你准备采用J2EE技术往你的web站点里添加新内容，而这个系统的其他部分是用CGI或者微软的IIS Server搭建的。<br><br>在这种情况下，怎样让你的应用系统从外观和感受(look and feel)上保持一致呢？一种办案就是采用J2EE技术全部重写，然后选用一种框架，比如Struts-Tiles，但这种办案的开发成本太高，不太现实。另一种可选方案是在你的应用系统的各个部分采用相同的Look and Feel。但这种方案会使维护站点变成噩梦，因为每当一个应用系统里面的Look and Feel需要改变的时候，你就需要让系统里的其他web应用保持同样的改变。<br><br>大多数用于解决这种商务需求的可用框架都有一个共同的缺点，他们不是平台相关就是框架相关。当你决定采用Tiles作为struts修饰器的时候，需要创建tiles定义文件tiles-defs.xml，然后在struts-config.xml里面声明forwards，引用这些tiles以修饰原始的JSP。<br>最简单的一种可能的解决方案是，全部采用纯html方式来生成你的web应用，每一个html页面都不需要知道自己将会被如何修饰，而是在外部采用某种机制来选择合适的修饰器修饰它们。这就是SiteMesh的功能。<br><br>SiteMesh是基于Java、J2EE和XML的开源框架，依赖于从Servlet 2.3版本里引入的新功能——过滤器(Filters)<br>安装和设置<br><br>按照以往的经验，学习任何新技术或新框架最好的办法，就是使用它来创建一个简单的应用程序。所以，我们将使用SiteMesh来创建一个简单的Struts应用程序。我们的应用程序包括三个页面：<br><br>&#8226;一个登录页面<br>&#8226;一个帮助页面，包括页头和页脚<br>&#8226;一个主页面，包括页头、页脚和页边菜单<br><br>下面是创建这个简单web应用程序的步骤：<br><br>1．SiteMesh基于过滤器，所以我们需要把SiteMesh过滤器通知给我们的web应用程序。在web.xml文件里加入如下几行：<br>
<pre><br><span style="COLOR: #33cccc">&lt;filter&gt;<br>  &lt;filter-name&gt;sitemesh&lt;/filter-name&gt;<br>  &lt;filter-class&gt;<br>      com.opensymphony.module.sitemesh.filter.PageFilter<br>  &lt;/filter-class&gt;<br>  &lt;init-param&gt;<br>    &lt;param-name&gt;debug.pagewriter&lt;/param-name&gt;<br>    &lt;param-value&gt;true&lt;/param-value&gt;<br>  &lt;/init-param&gt;<br>&lt;/filter&gt;<br>&lt;filter-mapping&gt;<br>  &lt;filter-name&gt;sitemesh&lt;/filter-name&gt;<br>  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br>&lt;/filter-mapping&gt;<br></span></pre>
<br>这几行是告诉web容器，所有对web应用的请求都会经由PageFilter&#8220;过滤&#8221;一下。PageFilter是sitemesh-2.1.jar里的一个类，你可以从http://www.opensymphony.com/sitemesh/download.html下载该jar包。<br><br>2．在WEB-INF目录下生成一个decorators.xml文件，内容如下：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;decorators defaultdir="/decorators"&gt;<br> <span style="COLOR: #99cc00"> &lt;!— 给需要页边菜单的页面配置页边菜单修饰器 --&gt;<br></span>  &lt;decorator name="sidemenu" page="sidemenu.jsp"&gt;<br>    &lt;pattern&gt;/home.jsp&lt;/pattern&gt;<br>  &lt;/decorator&gt;<br> <span style="COLOR: #99cc00"> &lt;!— 给需要页头和页脚的页面配置页头页脚修饰器 --&gt;<br></span>  &lt;decorator name="headerfooter" page="headerfooter.jsp"&gt;<br>    &lt;pattern&gt;/help.jsp&lt;/pattern&gt;<br>  &lt;/decorator&gt;<br>&lt;/decorators&gt;</span><br></pre>
<br>decorators.xml文件用来在你的应用程序里定义修饰器(decorators)。在这个文件里，每个&lt;decorator&gt;元素定义一个修饰器，name指定修饰器名，page指定修饰器所使用的JSP页面。&lt;pattern&gt;子元素指定这些修饰器如何应用到实际的页面上去。<br><br>在我们的示例web应用里，定义了两个修饰器：追加页头和页脚的headerfooter.jsp和追加页边菜单的sidemenu.jsp。我们想修饰help页面追加页头和页脚，所以我们追加了一个/help.jsp路径子元素给headerfooter.jsp修饰器。<br><br>3．在WebContent/decorators目录下创建headerfooter.jsp：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;%@ taglib<br>    uri="http://www.opensymphony.com/sitemesh/decorator"<br>    prefix="decorator" %&gt;<br>&lt;html&gt;<br>  &lt;head&gt;<br>    &lt;title&gt;<br>      My Site - <br>      &lt;decorator:title default="Welcome!" /&gt;<br>    &lt;/title&gt;<br>    &lt;decorator:head /&gt;<br>  &lt;/head&gt;<br>  &lt;body&gt;<br>    &lt;table&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt;<br>          &lt;H1&gt;<br>            SiteMesh Corporation<br>          &lt;H1&gt;<br>        &lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt;&lt;decorator:body /&gt;&lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt; SiteMesh copyright&lt;/td&gt;<br>      &lt;/tr&gt;<br>    &lt;/table&gt;<br>  &lt;/body&gt;<br>&lt;/html&gt;<br></span></pre>
<br>一个SiteMesh修饰器其实就是一个使用SiteMesh自定义标签的JSP页面。在我们的web应用里，当用户请求help页面的时候，SiteMesh会拦截这个请求，然后再把它发送给web应用。而当应用返回响应的时候，SiteMesh会结合headerfooter.jsp文件解析这个响应，遇到&lt;decorator:head/&gt;就插入响应文件的&lt;head&gt;，遇到&lt;decorator:body/&gt;就插入响应文件的&lt;body&gt;。最后，被headerfooter.jsp修饰过的文件会被返回给客户端。<br><br>4．在WebContent目录下创建help.jsp：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;HTML&gt;<br>&lt;HEAD&gt;<br>&lt;%@ page <br>language="java"<br>contentType="text/html; charset=ISO-8859-1"<br>pageEncoding="ISO-8859-1"<br>%&gt;<br>&lt;TITLE&gt;Help Page&lt;/TITLE&gt;<br>&lt;/HEAD&gt;<br>&lt;BODY&gt;<br>  Help Page <br>&lt;/BODY&gt;<br>&lt;/HTML&gt;<br></span></pre>
<br>这是一个在web应用里很常见的help页面。<br><br>5．在浏览器里请求help.jsp页面，测试SiteMesh安装是否正常。浏览器将会返回一个包含页头和页脚的help页面。<br><br>SiteMesh架构<br><br>SiteMesh架构基于PageFilter——一个Servlet过滤器。容器接收到页面请求时，会把请求传递给PageFilter，PageFilter收集应用程序的响应细节，生成自定义的响应对象，然后连同请求一起传递给web应用程序。web应用程序把响应资源写入到自定义响应对象里，再返回给PageFilter。<br><br>1．解析阶段<br>当控制返回给PageFilter的时候，它会检查web应用生成响应的内容类型(content type)，然后基于响应类型，生成不同的解析器来解析响应。比如，如果应用返回text/html类型的内容，SiteMesh会生成一个FastPageParser实例，并把web应用生成的页面传递给它。FastPageParser会解析这个页面，提取出这个页面的header、footer、title 等内容。<br><br>2．修饰阶段<br><br>解析结束后，SiteMesh开始修饰页面。这一阶段分成两部分：<br><br>a．决定如何修饰<br><br>SiteMesh有一个概念，叫做修饰器映射，实现这个概念的接口是DecoratorMapper(有init()和getDecorator()方法)。映射器在sitemesh.xml里声明。在sitemesh.xml文件里，每一个映射器都是它上一个映射器的父映射。当SiteMesh需要一个修饰器来修饰页面的时候，会在sitemesh.xml里查找映射器，生成找到的第一个映射器的实例并调用getDecorator()方法，在这个方法里尝试查找针对那个页面的修饰器。如果找到了就返回；否则，调用父映射器的getDecorator()方法，反复进行这个过程，直到找到正确的修饰器。<br><br>b．应用修饰<br><br>找到修饰器后，SiteMesh会把请求分发给它。修饰器JSP页面会访问在前阶段里解析出来的页面信息。使用各种SiteMesh自定义标签来提取页面信息不同的部分(比如header、footer和title)并把它们插入到输出文件合适的位置上去。<br><br>你可以在sitemesh.xml文件里自定义使用哪个页面解析器来解析指定的内容类型或者使用哪种修饰器映射方案，比如：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>&lt;sitemesh&gt;<br>  &lt;property name="decorators-file" value="/WEB-INF/decorators.xml"/&gt;<br>  &lt;excludes file="${decorators-file}"/&gt;<br>  &lt;page-parsers&gt;<br>    &lt;parser content-type="text/html" <br>        class="com.opensymphony.module.sitemesh.parser.FastPageParser" /&gt;<br>  &lt;/page-parsers&gt;<br>  &lt;decorator-mappers&gt;<br>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper"&gt;<br>      &lt;param name="property.1" value="meta.decorator" /&gt;<br>      &lt;param name="property.2" value="decorator" /&gt;<br>    &lt;/mapper&gt;<br>    <span style="COLOR: #99cc00">&lt;!-- Mapper for localization --&gt;<br></span>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper"&gt;<br>      &lt;param name="match.en" value="en" /&gt;<br>      &lt;param name="match.zh" value="zh" /&gt;<br>    &lt;/mapper&gt;<br>    <span style="COLOR: #99cc00">&lt;!-- Mapper for browser compatibility --&gt;<br></span>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"&gt;<br>      &lt;param name="match.MSIE" value="ie" /&gt;<br>      &lt;param name="match.Mozilla/" value="ns" /&gt;<br>    &lt;/mapper&gt;<br>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"&gt;<br>      &lt;param name="decorator" value="printable" /&gt;<br>      &lt;param name="parameter.name" value="printable" /&gt;<br>      &lt;param name="parameter.value" value="true" /&gt;<br>    &lt;/mapper&gt;<br>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper"&gt;<br>      &lt;param name="decorator.parameter" value="decorator" /&gt;<br>      &lt;param name="parameter.name" value="confirm" /&gt;<br>      &lt;param name="parameter.value" value="true" /&gt;<br>    &lt;/mapper&gt;<br>    &lt;mapper <br>        class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper"&gt;<br>      &lt;param name="config" value="${decorators-file}" /&gt;<br>    &lt;/mapper&gt;<br>  &lt;/decorator-mappers&gt;<br>&lt;/sitemesh&gt;<br></span></pre>
<br>在这个列表里，&lt;property name="decorators-file"&gt;指定了用于定义修饰器的文件。&lt;page-parsers&gt;定义了SiteMesh可以处理的内容类型。每一个&lt;parser&gt;子元素指定哪一个解析器解析哪一种特定的内容类型。在我们的示例sitemesh.xml文件里，我们告诉SiteMesh使用FastPageParser解析text/html类型的内容。默认地，SiteMesh只可以处理HTML，但我们可以创建自己的解析器来处理其他的内容类型。<br><br>&lt;decorator-mappers&gt;子元素定义了映射方案，SiteMesh使用这个映射方案来查找修饰指定页面的修饰器。你可以使用&lt;param&gt;子元素来配置每一个映射器。SiteMesh会把这些配置信息包装成java.util.Properties对象传递给映射器的init()方法。<br><br>区域相关的修饰器<br><br>在我们的示例sitemesh.xml文件里，有下面几行标签：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;mapper class="com.opensymphony.module.sitemesh.mapper.LanguageDecoratorMapper"&gt;<br>  &lt;param name="match.en" value="en" /&gt;<br>  &lt;param name="match.zh" value="zh" /&gt;<br>&lt;/mapper&gt;</span><br></pre>
<br>当查找一个应用于页面的修饰器时，SiteMesh会首先读取请求头部的Accept-Language信息。如果匹配en区域，SiteMesh会在修饰器JSP文件名末尾追加-en。在我们的例子里，如果请求定义了修饰器headerfooter.jsp的help.jsp页面，并且使用的是区域是英国，SiteMesh会首先查找并应用headerfooter-en.jsp修饰器，如果找不到再去应用headerfooter.jsp。<br><br>浏览器相关的修饰器<br><br>可以使用AgentDecoratorMapper来保证浏览器的兼容性：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;mapper <br>class="com.opensymphony.module.sitemesh.mapper.AgentDecoratorMapper"&gt;<br>  &lt;param name="match.MSIE" value="ie" /&gt;<br>  &lt;param name="match.Mozilla/" value="ns" /&gt;<br>&lt;/mapper&gt;</span><br></pre>
<br>这意味着当SiteMesh查找一个修饰器来修饰页面的时候，会首先提取出请求头部的User-Agent信息。如果是IE，就加上-ie到修饰器的文件名末尾，并查找和应用这个修饰器。如果找不到这样的修饰器，则继续应用headerfooter.jsp。<br><br>高级SiteMesh<br><br>SiteMesh提供映射器，让每一个页面参与到寻找自己修饰器的过程中去。<br><br>PrintableDecoratorMapper<br><br>大多数的web站点都提供了一个获得可打印版本页面的功能。所谓可打印版本，一般是指去除了页头、页尾和页边菜单，并使用了另一套样式表的页面。在SiteMesh里，我们可以使用PrintableDecoratorMapper来提供这个功能。要使用这个映射器，需要在sitemesh.xml里追加如下几行：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;mapper <br>class= "com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper"&gt;<br>  &lt;param name="decorator" value="printable" /&gt;<br>  &lt;param name="parameter.name" value="printable" /&gt;<br>  &lt;param name="parameter.value" value="true" /&gt;<br>&lt;/mapper&gt;</span><br></pre>
<br>传递给PrintableDecoratorMapper的三个配置参数会被包装成java.util.Properties对象传递给init()方法。<br><br>&#8226;decorator<br>用来生成可打印版本页面的修饰器名。<br><br>&#8226;parameter.name<br>用来通知SiteMesh我们需要一个可打印版本的请求参数名。比如在我们的例子里，通过在查询字符串里追加printable=true参数传递<br><br>&#8226;parameter.value<br>设置可打印参数为何值时SiteMesh提供可打印版本的页面。<br><br>PageDecoratorMapper<br><br>页面可以通过定义META属性来重载指定修饰自己的修饰器名。<br><br>要使用这个映射器，需要在sitemesh.xml文件里加入如下几行：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;mapper <br>class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper"&gt;<br>  &lt;param name="property.1" value="meta.decorator" /&gt;<br>&lt;/mapper&gt;</span><br></pre>
<br>PageDecoratorMapper可以获取一个参数列表。在我们的例子里，提供了一个参数名，指定了通过META属性来取得修饰器名。所以如果我们希望使用test修饰器来修饰页面，则在该页头部加入：<br><br>&lt;META name="decorator" content="test"&gt;<br><br>PageDecoratorMapper提供了一种静态的方法来让页面选择自己想要使用的修饰器。另外，页面还可以通过使用ParameterDecoratorMapper在运行时指定要使用的修饰器。<br><br>ParameterDecoratorMapper<br><br>要使用ParameterDecoratorMapper，在sitemesh.xml里追加如下几行：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;mapper <br>class= "com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper"&gt;<br>  &lt;param name="decorator.parameter" value="decorator" /&gt;<br>  &lt;param name="parameter.name" value="confirm" /&gt;<br>  &lt;param name="parameter.value" value="true" /&gt;<br>&lt;/mapper&gt;</span><br></pre>
<br>三个参数的意义分别如下：<br><br>&#8226;decorator.parameter<br>指定修饰器所使用的请求参数名。<br><br>&#8226;parameter.name<br>确定使用请求修饰器的确认参数名。<br><br>&#8226;parameter.value<br>确定使用请求修饰器的确认参数值。<br><br>比如，如果你想使用test修饰器来修饰help.jsp，可以像下面这样访问help.jsp<br><br>help.jsp?decorator=test&amp;confirm=true<br><br>除了以上这些映射器以外，SiteMesh还提供了更多有用的映射器，比如：<br><br>&#8226;FrameSetDecoratorMapper<br>当页面是Frame的时候使用。<br><br>&#8226;CookieDecoratorMapper<br>可以通过cookie来指定想要使用的修饰器。<br><br>&#8226;RobotDecoratorMapper<br>当请求者被确人为robot的时候使用指定的修饰器。你可以手动的在请求头部追加robot关键字，或者通过修饰器来做。<br><br>Velocity 和 Freemarker 修饰器<br><br>SiteMesh并没有限制你只能修饰JSP页面。你可以自由的选择想要修饰的对象，比如Velocity或者Freemarker。Velocity和Freemarker是一种可被用于生成web页面的模板语言。这些语言比JSP更加的简单易用，但在可编程性方面不如JSP灵活。<br><br>SiteMesh通过两个servlet支持这两种模板语言，这两个servlet也被定义在SiteMesh.jar文件里。我们可以像这样在web.xml里声明这两个servlet：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;servlet&gt;<br>  &lt;servlet-name&gt;sitemesh-velocity&lt;/servlet-name&gt;<br>  &lt;servlet-class&gt; <br>    com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet<br>  &lt;/servlet-class&gt;<br>&lt;/servlet&gt;<br><span style="COLOR: #99cc00">&lt;!--Declare servlet for handling freemarker requests --&gt;<br></span>&lt;servlet&gt;<br>  &lt;servlet-name&gt;sitemesh-freemarker&lt;/servlet-name&gt;<br>  &lt;servlet-class&gt;<br>    com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet<br>  &lt;/servlet-class&gt;<br>  &lt;init-param&gt;<br>    &lt;param-name&gt;TemplatePath&lt;/param-name&gt;<br>    &lt;param-value&gt;/&lt;/param-value&gt;<br>  &lt;/init-param&gt;<br>  &lt;init-param&gt;<br>    &lt;param-name&gt;default_encoding&lt;/param-name&gt;<br>    &lt;param-value&gt;ISO-8859-1&lt;/param-value&gt;<br>  &lt;/init-param&gt;<br>&lt;/servlet&gt;<br><span style="COLOR: #99cc00">&lt;!-- Velocity servlet should serve all requests with .vm extension--&gt;<br></span>&lt;servlet-mapping&gt;<br>  &lt;servlet-name&gt;sitemesh-velocity&lt;/servlet-name&gt;<br>  &lt;url-pattern&gt;*.vm&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br><span style="COLOR: #99cc00">&lt;!-- FreeMarker servlet should serve all requests with .dec extension--&gt;<br></span>&lt;servlet-mapping&gt;<br>  &lt;servlet-name&gt;sitemesh-freemarker&lt;/servlet-name&gt;<br>  &lt;url-pattern&gt;*.dec&lt;/url-pattern&gt;<br>&lt;/servlet-mapping&gt;<br></span></pre>
<br>当然，我们还需要在lib文件夹里引入freemarker.jar、velocity-dep.jar和velocity-tools-view.jar。这些jar文件已经包含在SiteMesh的发布包里了。下面让我们修改第一个示例应用，使用Velocity和Freemarker修饰器来取代JSP。在我们第一个示例应用里定义了两个修饰器：headerfooter和sidemenu。下面我们创建一个headerfooter.dec：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;html&gt;<br>  &lt;head&gt;<br>    &lt;title&gt;My Site - $Advanced SiteMesh&lt;/title&gt;<br>      ${head}<br>  &lt;/head&gt;<br>  &lt;body&gt;<br>    &lt;table border="1"&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt;SiteMesh Corporation&lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt;${body}&lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt;SiteMesh copyright&lt;/td&gt;<br>      &lt;/tr&gt;<br>    &lt;/table&gt;<br>  &lt;/body&gt;<br>&lt;/html&gt;</span><br></pre>
<br>在这个页面里，我们使用Freemarker模板来请求header、footer和title，而不是使用JSP自定义标签，但页面布局是一样的。当容器接收到一个.dec扩展名的页面请求时，会把这个请求传递给FreemarkerDecoratorServlet，后者将会调用FreemarkerDecorator修饰生成的HTML页面。我们使用$Advanced SiteMesh模板来访问应用生成的web页面的title，${head}访问head，${body}访问body。Freemarker提供了非常丰富的模板，想深入研究的话可以参考http://www.javaworld.com/jw-01-2001/jw-0119-freemarker.html。<br><br>相似的，在decorators目录下创建sidemenu.vm文件，这是Velocity修饰器文件：<br>
<pre class=codeStyle><br><span style="COLOR: #33cccc">&lt;html&gt;<br>  &lt;head&gt;<br>    &lt;title&gt;My Site - $title&lt;/title&gt;<br>      $head<br>  &lt;/head&gt;<br>  &lt;body&gt;<br>    &lt;table border="1"&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt; SiteMesh Header &lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt; Sidemenu &lt;/td&gt;<br>        &lt;td&gt; $body &lt;/td&gt;<br>      &lt;/tr&gt;<br>      &lt;tr&gt;<br>        &lt;td&gt; SiteMesh Footer &lt;/td&gt;<br>      &lt;/tr&gt;<br>    &lt;/table&gt;<br>  &lt;/body&gt;<br>&lt;/html&gt;</span><br></pre>
<br>使用$title模板取代&lt;decorator:title/&gt;，使用$head和$body Velocity模板来取代相应的JSP自定义标签。<br><br>结论<br><br>基于过滤器的SiteMesh是一个非常灵活和简单易用的修饰器框架。但它还是存在着一些问题。首先，从Servlet 2.3版本才开始支持过滤器，所以一些早期版本的应用服务器无法支持SiteMesh。在使用SiteMesh之前请先检查一下您想使用的应用服务器是否支持过滤器。<br><br>另外，过滤器只有在使用浏览器请求一个页面的时候才能生效。所以，如果你通过浏览器访问home.jsp，它将被修饰，但如果你使用Servlet的RequestDispatcher.include()或者forward()来控制home.jsp，修饰器就不起作用了。但是不用担心，从Servlet 2.4版本开始，你可以配置过滤器适用的环境，包括forward和include的情况下都可以使用了。 <br><br><br><br>
<img src ="http://www.blogjava.net/livery/aggbug/125299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/livery/" target="_blank">心情经纬</a> 2007-06-20 11:34 <a href="http://www.blogjava.net/livery/articles/125299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>