Advertisement

SiteMesh3简介及使用

阅读量:

最近项目用到SiteMesh3,研究学习一段时间后决定写篇博文来记录收获。

SiteMesh

我对SiteMesh进行了详细介绍,并对其工作原理进行了阐述。
该技术通过以下方式实现了对数据流量的实时监控与过滤:
首先,在Maven包管理器中添加了SiteMesh依赖项;
其次,在WebXML配置文件中引入了SiteMesh过滤器;
随后,在一个专门设计的装饰页面上实现了对原始内容的呈现;
接着,在另一个独立的内容页面上展示了经过过滤后的数据;
最后,在上述两个页面的基础上完成了整个系统的全面部署与测试。
该方法提供了两种实现方案:
第一种基于XML的数据处理方式;
第二种则采用Java语言进行编程实现。

复制代码
* * 6查看效果
  * 7高级配置 
* 1XML形式配置
* 2Java形式配置

  * 自定义标签的使用 
* 装饰页面decorator
* 内容页面content
* 效果

介绍

SiteMesh 是一个用于网页排版与修饰的工具。通过它,我们可以实现内容与页面结构的分离,并从而促进不同页面之间的信息共享。

Sitemesh是一个集网页布局设计与功能整合于一体的框架系统。其主要应用于大型项目中需求一致性的网页设计与展示。
该框架不仅支持动态生成的内容(如jsp、php、asp等),还特别注重对静态资源元素(如htm)的支持。
值得注意的是,
其独特的功能模块能够将外部HTML代码直接嵌入至项目文档中作为独立组件。
尽管采用Java语言作为开发平台,
但该系统仍能与现有Web应用系统无缝集成,
充分体现了GOF(可复用性)模式中的装饰模式特性。

下图是SiteMesh的结构图

这里写图片描述

工作原理

SiteMesh是由Servlet提供的filter实现的,即为过滤流的技术。它通过从响应中截取数据,并对其进行包装处理后重新发送给客户端。

其中涉及到的两个名词是:装饰页面(decorator page)和被修饰的内容页面(Content page),即通过SiteMesh对Content Page进行修饰处理后所生成的一致布局与外观效果,并将结果传递给客户。

运行SiteMesh3至少需要:

  • JDK 1.5
  • 一个Servlet 2.5兼容容器
  • SiteMesh运行时库

配置及使用

下载

wiki上的下载链接为:http://wiki.sitemesh.org/wiki/display/sitemesh3/Home

该版本的GitHub下载链接为(附带演示文稿),请访问https://github.com/sitemesh/sitemesh3/releases/tag/3.0.1


1、添加maven依赖

pom.xml文件添加以下依赖:

复制代码
    <!--sitemesh-->
    <dependency>
     <groupId>org.sitemesh</groupId>
     <artifactId>sitemesh</artifactId>
     <version>3.0.1</version>
     </dependency>

2、web.xml中添加SiteMesh过滤器

复制代码
    <web-app>
    
    ...
    
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    </web-app>

3、创建一个“装饰页面”(decorator page)

该装饰页面用于实现Web应用程序中的常见布局和样式设计。这一界面设计模块由HTML代码中的标题标记、 HEAD 节和 BODY 节构成。该界面设计必须具备相应的功能模块以支持这些基本组件。

复制代码
    <HTML>
      <HEAD>
    <title> <sitemesh:write property ='title'/> </ title>
    <sitemesh:write property ='head'/>
      </HEAD>
      <BODY>
    <sitemesh:write property ='body'/>
      </BODY>
    </HTML>

标签<sitemesh:write property='...'/>会被SiteMesh重新编写为一个能够保存来自'被装饰页面'(content page)中的值的标签。该功能允许从'被装饰页面'(content page)中提取更多属性,并能根据需求自定义规则以适应不同的应用场景。在WEB应用程序开发中,请确保在构建/decorator.html文件时正确配置相关属性设置以实现预期效果。

复制代码
    <html>
      <head>
    <title>SiteMesh example: <sitemesh:write property='title'>Title goes here</sitemesh:write></title>
    <style type='text/css'>
      body { font-family: arial, sans-serif; background-color: #ffffcc; }
      h1, h2, h3, h4 { text-align: center; background-color: #ccffcc; border-top: 1px solid #66ff66; }
      .disclaimer { text-align: center; border-top: 1px solid #cccccc; margin-top: 40px; color: #666666; font-size: smaller; }
    </style>
    <sitemesh:write property='head'/>
      </head>
      <body>
    
    <h1 class='title'>SiteMesh example site: <sitemesh:write property='title'>Title goes here</sitemesh:write></h1>
    
    <sitemesh:write property='body'>Body goes here. Blah blah blah.</sitemesh:write>
    
    <div class='disclaimer'>Site disclaimer. This is an example.</div>
    <div class='navigation'>
      <b>Examples:</b>
      [<a href="./">Static example</a>]
      [<a href="demo.jsp">Dynamic example</a>]
    </div>
    
      </body>
    </html>

在这一案例中,默认情况下使用的网页模板是一个非动态格式的.html文件。然而,在需要实现动态展示时,则可考虑采用JSP、FreeMarker等技术进行构建。

4、创建一个“被装饰页面”(content page)

复制代码
    <html>
      <head>
    <title>Hello World</title>
      </head>
      <body>
    
    <p>Well hello there, fine world.</p>
    <p>And so concludes this <b>SiteMesh</b> example.</p>
    
    <h2>How it works</h2>
    <ul>
      <li>This page (<code>/index.html</code>) contains vanilla HTML content.</li>
      <li>SiteMesh is configured (in <code>/WEB-INF/web.xml</code>) to apply a decorator to all paths (<code>/*</code>).</li>
      <li>The decorator (<code>/decorator.html</code>) contains the common look and feel that is applied to the site.</li>
    </ul>
    
      </body>
    </html>

采用类似装饰页面的风格,在这种情况下,“被设计为能够充当被 decorator 的对象”的场景下也常见于由 Servlet 引擎动态生成的情况(例如 JSP)。


5、配置

SiteMesh配置支持两种方法 : XMLJava

5.1、XML方式

在工程的 /WEB-INF/sitemesh3.xml中添加以下设置:

复制代码
    <sitemesh>
      <mapping path="/*" decorator="/decorator.html"/>
    </sitemesh>
5.1、Java方式

要采用Java提供的配置方案以实现自定义的SitMesh过滤器。
具体来说,
自定义的SitMesh过滤器必须继承org.sitemesh.config.ConfigurableSiteMeshFilter类,
并通过重定义applyCustomConfiguration(SiteMeshFilterBuilder builder)方法来完成特定功能。

复制代码
    package com.wangxiaoan1234;
    
    import org.sitemesh.builder.SiteMeshFilterBuilder;
    import org.sitemesh.config.ConfigurableSiteMeshFilter;
    
    public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
    
    @Override
    protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
        builder.addDecoratorPath("/*", "/decorator.html");
    }
    
    }

在web.xml中应自定义一个经过修改的SiteMesh过滤器

web.xml中应自定义一个经过修改的SiteMesh过滤器

复制代码
    <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.wangxiaoan1234.MySiteMeshFilter</filter-class>
    </filter>
    
    <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

6、查看效果

本地查看内容页面.html效果如下:

这里写图片描述

通过SiteMesh3装饰后访问效果如下:

这里写图片描述

查看该效果页面源代码如下:

复制代码
    <html>
      <head>
    <title>SiteMesh example: Hello World (Dynamic)</title>
    <style type='text/css'>
      body { font-family: arial, sans-serif; background-color: #ffffcc; }
      h1, h2, h3, h4 { text-align: center; background-color: #ccffcc; border-top: 1px solid #66ff66; }
      .disclaimer { text-align: center; border-top: 1px solid #cccccc; margin-top: 40px; color: #666666; font-size: smaller; }
    </style>
    
    
    <style type='text/css'>
      .date { font-weight: bold; padding: 10px; font-size: larger; }
    </style>
    
      </head>
      <body>
    
    <h1 class='title'>SiteMesh example site: Hello World (Dynamic)</h1>
    
    
    
    <p>This page demonstrates that dynamic content can be decorated in the same way as static content.</p>
    <p>This is a simple JSP that shows the date and time on the server is now:</p>
    
    <div class='date'>Tue Aug 15 14:25:41 CST 2017</div>
    
    <p>Of course, with SiteMesh you are not limited to JSP. Because it's a Servlet Filter, both content and decorators can be
    generated by any technology in your ServletEngine, including: static files, JSP, Velocity, FreeMarker, JSF, MVC frameworks, JRuby.... you get the point.</p>
    
    
    
    <div class='disclaimer'>Site disclaimer. This is an example.</div>
    <div class='navigation'>
      <b>Examples:</b>
      [<a href="./">Static example</a>]
      [<a href="demo.jsp">Dynamic example</a>]
    </div>
    
      </body>
    </html>

7、高级配置

7.1、XML形式配置

sitemesh3.xml文件如下:

复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <sitemesh>
    <!--默认情况下,sitemesh 只对 HTTP 响应头中 Content-Type 为 text/html 的类型进行拦截和装饰,我们可以添加更多的 mime 类型-->
    <mime-type>text/html</mime-type>
    <mime-type>application/vnd.wap.xhtml+xml</mime-type>
    <mime-type>application/xhtml+xml</mime-type>
    
    <!-- 默认装饰器,当下面的路径都不匹配时,启用该装饰器进行装饰 -->
    <mapping decorator="/default-decorator.html"/>
    
    <!--不同的匹配路径采用不同的装饰页面-->
    <mapping path="/admin/*" decorator="/another-decorator.html"/>
    <mapping path="/*.special.jsp" decorator="/special-decorator.html"/>
    
    <!--一个匹配路径同时采用不同的装饰页面-->
    <mapping>
        <path>/articles/*</path>
        <decorator>/decorators/article.html</decorator>
        <decorator>/decorators/two-page-layout.html</decorator>
        <decorator>/decorators/common.html</decorator>
     </mapping>
    
    <!-- 满足该匹配路径将不被装饰 -->
    <mapping path="/login.htm" exclue="true" />
    
    <!-- 自定义标签 -->
    <content-processor>
        <tag-rule-bundle class="com.something.CssCompressingBundle" />
        <tag-rule-bundle class="com.something.LinkRewritingBundle"/>
      </content-processor>
    </sitemesh>
7.2、Java形式配置

对应Java配置如下(同理还是在web.xml中引用自己的SiteMesh过滤器):

复制代码
    package com.wangxiaoan1234;
    
    import org.sitemesh.builder.SiteMeshFilterBuilder;
    import org.sitemesh.config.ConfigurableSiteMeshFilter;
    
    public class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
    
    @Override
    protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
        //默认装饰器,当下面的路径都不匹配时,启用该装饰器进行装饰
        builder.addDecoratorPath("/*", "/decorator.html")
            //添加更多的 mime 类型
            .setMimeTypes("text / html","application / xhtml + xml","application / vnd.wap.xhtml + xml")
            //不同匹配路径采用不同的装饰页面
            .addDecoratorPath("/admin/*", "/another-decorator.html")
            .addDecoratorPath("/*.special.jsp", "/special-decorator.html")
            //一个匹配路径同时采用不同的装饰页面
            .addDecoratorPaths("/articles/*", "/decorators/article.html",
                    "/decoratos/two-page-layout.html",
                    "/decorators/common.html")
            //满足该匹配路径将不被装饰
            .addExcludedPath("/javadoc/*")
            //添加自定义标签
            .addTagRuleBundle(new CssTagRuleBundle());
    }
    }

其中自定义标签类格式如下:

复制代码
    package com.wangxiaoan1234;
    
    import org.sitemesh.SiteMeshContext;
    import org.sitemesh.content.ContentProperty;
    import org.sitemesh.content.tagrules.TagRuleBundle;
    import org.sitemesh.content.tagrules.html.ExportTagToContentRule;
    import org.sitemesh.tagprocessor.State;
    
    /** * 自定义标签
     */
    public class CssTagRuleBundle implements TagRuleBundle {
    @Override
    public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
        defaultState.addRule("my-css",
                new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("my-css"), false));
        defaultState.addRule("my-footer",
                new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("my-footer"), false));
    }
    
    @Override
    public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
    }
    }

在web.xml中还可以指定请求来源:

复制代码
    <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.wangxiaoan1234.MySiteMeshFilter</filter-class>
      </filter>
      <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>REQUEST</dispatcher>
      </filter-mapping>

该 dispatcher 元素共有四个可能取值:即 REQUEST, FORWARD, INCLUDE, 和 ERROR. 该元素确保滤镜将作用于直接来自客户端的请求、经服务器转发的请求、经应用包含的请求以及经 <error-page> 导致的请求. 若未指定任何 <dispatcher> 元素,则默认取值为 REQUEST.

自定义标签的使用:

装饰页面(decorator):
复制代码
    <html>
    <head>
      <title>SiteMesh example: <sitemesh:write property='title'>Title goes here</sitemesh:write></title>
      <style>
    <sitemesh:write property='my-css'/>
      </style>
      <sitemesh:write property='head'/>
      </head>
      <body>
    <div>
      <p>pppppppppppppppppppppp</p>
    </div>
      <siteMesh:write property='my-footer'/>
      </body>
    </html>
内容页面(content):
复制代码
    <html>
      <head>
    <title>Hello World</title>
    <my-css>
      div p {
      color : red;
      }
    </my-css>
      </head>
      <body>
    <p>Well hello there, fine world.</p>
    <p>And so concludes this <b>SiteMesh</b> example.</p>
      <my-footer>
    <div style="text-align: center">
      &copy;wangxiaoan1234.com
    </div>
      </my-footer>
      </body>
    </html>
效果:
这里写图片描述

效果页面源码:

复制代码
    <html>
    <head>
      <title>SiteMesh example: Hello World</title>
      <style>
    
      div p {
      color : red;
      }
    
      </style>
    
    
    
    
      </head>
      <body>
    <div>
      <p>pppppppppppppppppppppp</p>
    </div>
    
    <div style="text-align: center">
      &copy;wangxiaoan1234.com
    </div>
    
      </body>
    </html>

未完待续。。。

参考:

1、wiki

2、罗韬

3、开源中国社区

4、百度百科

全部评论 (0)

还没有任何评论哟~