所属专栏: Java开发经验记录
 

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

SiteMesh


介绍

SiteMesh 是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的。

Sitemesh是由一个基于Web页面布局、装饰以及与现存Web应用整合的框架。它能帮助我们在由大量页面构成的项目中创建一致的页面布局和外观,如一致的导航条,一致的banner,一致的版权,等等。它不仅仅能处理动态的内容,如jsp,php,asp等产生的内容,它也能处理静态的内容,如htm的内容,使得它的内容也符合你的页面结构的要求。甚至于它能将HTML文件象include那样将该文件作为一个面板的形式嵌入到别的文件中去。所有的这些,都是GOF的Decorator模式的最生动的实现。尽管它是由java语言来实现的,但它能与其他Web应用很好地集成。

下图是SiteMesh的结构图


工作原理

SiteMesh是基于Servlet的filter的,即过滤流。它是通过截取response,并进行装饰后再交付给客户。

其中涉及到两个名词: 装饰页面(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上3.0.1版本下载地址为(含demo):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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

该装饰页面包含Web应用程序中常见得布局和样式,它是一个包含<title><head><body>元素的模板。它至少要包含:

<HTML>
<HEAD>
<title> <sitemesh:write property ='title'/> </ title>
<sitemesh:write property ='head'/>
</HEAD>
<BODY>
<sitemesh:write property ='body'/>
</BODY>
</HTML>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

标签<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在这个例子中,装饰页面是一个静态的.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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

像装饰页面一样,被装饰页面可以是静态文件,也可以是由Servlet引擎动态生成(例如JSP)。


5、配置

SiteMesh配置支持两种方法 : XMLJava

5.1、XML方式

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

<sitemesh>
<mapping path="/*" decorator="/decorator.html"/>
</sitemesh>
  • 1
  • 2
  • 3

5.1、Java方式

要使用Java的配置方式,自定义的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");
} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

既然使用Java配置方式,就不再需要sitemesh3.xml文件,但是在web.xml中要使用自己重写的SiteMesh过滤器。
即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>
</filter-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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());
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

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

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) {
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

<dispatcher>这个元素有四个可能的值:即REQUESTFORWARDINCLUDEERROR,这个元素使得filter将会作用于直接从客户端过来的request,通过forward过来的request,通过include过来的request和通过<error-page>过来的request。如果没有指定任何<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

内容页面(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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

效果:

效果页面源码:

<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>

SiteMesh3简介及使用的更多相关文章

  1. Sitemesh3的使用及配置

    1 . Sitemesh 3 简介 Sitemesh 是一个网页布局和修饰的框架,基于 Servlet 中的 Filter,类似于 ASP.NET 中的‘母版页’技术.参考:百度百科,相关类似技术:A ...

  2. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  3. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  4. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

  5. REST简介

    一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...

  6. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  7. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  8. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  9. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

随机推荐

  1. Gradle Repository

    // 该init.gradle文件,请保存到${USER_HOME}/.gradle/文件夹下,如:C:\Users\Administrator\.gradle allprojects { repos ...

  2. Windows10 引导修复

    [问题]最近遇到一些用户使用的操作系统为Win10,但是使用过程中由于错误系统优化.卸载软件错误.误删系统文件.windows更新错误等,影响系统BCD引导文件,造成开机出现该BCD蓝屏报错,如下图所 ...

  3. 多线程校验url的种种。。。

    东西不经常看就容易忘,这两天抽空写了一个补丁库url验证工具,挺曲折的,记录一下需求大概流程如下:转换补丁库为xml,解析xml得到所有url,多线程校验url.就不到100行有效代码,断断续续写了三 ...

  4. iP私网地址

    私网地址范围:A类10.0.0.0~255.255.255 B类172.16.0.0~172.31.255.255 C类192.168.0.0~192.168.255.255

  5. Java的异常机制

    Java的异常机制 (一)异常的概念 异常是指程序在编译或运行时出现的导致程序不能继续编译或运行的状况.. (二)Throwable类 Throwable类继承自Object类,是Java中所有错误或 ...

  6. MySQL查询缓存总结

    可以通过下面的SQL查看当前查询缓存相关参数状态: show variables like '%query_cache%'; 1)  query_cache_type 查询缓存类型: 0 表示始终不适 ...

  7. npm ERR! File exists: /XXX/xxx npm ERR! Move it away, and try again.

    今天抽空将我的静态服务 ks-server 之前留下的 bug(在node低版本情况下报错)维护了一下. 当我重新 npm link 时,如下错误: npm WARN ks-server@1.0.2 ...

  8. particular.js

    参数 键值 参数选项/ 说明 实例 particles.number.value number   数量 40 particles.number.density.enable boolean    t ...

  9. springboot缓存注解——@CachePut

    @CachePut:既调用方法,又更新缓存数据:修改了数据库的某个数据,同时又更新缓存 运行时机: 先调用目标方法 将目标方法的结果缓存起来 注意: @Cacheable的key不能用#result来 ...

  10. archlinux 装完系统连接 wifi 网络

    查看 IP 地址 ip a 注:没有看到 IP 地址,确认没有网络.或者也可以使用命令 ping www.baidu.com 测试是否有网络. 执行该指令: sudo systemctl start ...