引入:

最近在review别的团队的代码,看到他们团队使用了sitemesh,以前对这个不是很了解,刚好借助他们源代码,这里简单研究了下:

简单介绍:

其实sitemesh使用了页面装饰技术,它主要就是用一个或者多个装饰器应用于某些给定页面,最终产生被装饰器装饰后的页面。

具体过程是:

(1)sitemesh通过Filter来拦截页面访问 (可以猜想:肯定会有个url-pattern,表明此url被适用于某装饰器,等会具体讲 )

(2)一旦拦截到,则根据被访问的url来找到合适的装饰模板(可以猜想:肯定有一个模板定义文件,在其中定义了模板和模板使用的url之间的映射关系)

(3)提取被访问的页面的内容,放到装饰模板中给定的位置(这几乎是废话,因为这是组合页面技术,肯定输入有2个,一个是模板,一个是被访问页面,模板肯定会给出一些可配置的点,然后用placeholder表示,然后这些placeholder中放入的内容肯定由真实页面提供,放真实页面的内容肯定有个标记,这个标记符合模板上的标记从而不会找错,等会可以验证)

(4)装饰后的页面发送给客户端。

以上是我对于这个框架的开始的猜想,接下来就是去验证这些猜想。

实践:

(1)首先,如何做到sitemesh通过filter来拦截页面访问呢?根据常识,一般web应用过滤器都是定义在web.xml中的,所以我们去找:

1
2
3
4
5
6
7
8
9
<!-- sitemesh config -->
    <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>

从这里可以很清楚的看到,我们配置了 sitemesh过滤器,然后要对所有的页面都适用这个过滤器,当然了,要过滤器生效,还必须有相应的jar包,并且放在WEB-INF/lib下,这个是常识,因为他们项目中使用了maven,所以我们肯定会在pom.xml中找到对应的depenency:

1
2
3
4
5
6
<!-- sitemesh -->
        <dependency>
            <groupId>opensymphony</groupId>
            <artifactId>sitemesh</artifactId>
            <version>2.4.2</version>
        </dependency>

(2)现在我们来看第二步,肯定有个模板定义文件,定义了模板文件和其适用的文件之间的关系。这里就有2个概念了,一个是一般文件(可以说比较素的文件), 一种是模板文件(它定义了比较花哨的结构和外观),素文件我们不讲了,就是一般页面(比如jsp),然后模板文件,肯定是带有placeholder的页面文件,所以我们找到了这些文件:

显然,在他们的项目中,这些模板文件是放在WEB-INF/decorators中的,并且从这里可以看出他们定义了2个模板文件,一个叫blog_main.jsp,另一个叫main.jsp,然后他们的一般文件都是放在WEB-INF/jsp中的来加强安全性。我们随便打开一个模板文件,比如blog_main.jsp:

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
<!DOCTYPE HTML>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
<%@ page language="java" contentType="text/html; charset=utf-8"  pageEncoding="utf-8"%>
<html lang="en">
    <head>
                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                      
        <link rel="icon" href="${contextPath}/images/favicon.ico" type="image/x-icon" />
        <link rel="shortcut icon" href="${contextPath}/images/favicon.ico" type="image/x-icon" />
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="${cssRootPath}/common.css">
        <jsp:include page="${jspRootPath}/includes/global/incScript.jsp"/>
        <!-- 从被装饰页面获取title标签内容,并设置默认值-->
        <title><decorator:title default="Blog - Shokay"/></title>
        <!-- 从被装饰页面获取head标签内容 -->
        <decorator:head/>
    </head>
    <body>
        <jsp:include page="${jspRootPath}/includes/common/incPageTopHideBar.jsp" />
        <jsp:include page="${jspRootPath}/includes/common/incPageTopBar_blog.jsp" />
        <div class="main-body">
             <decorator:body />
        </div>
                                                                                                                                                                                                                                                                                                                                                                                      
    </body>
                                                                                                                                                                                                                                                                                                                                                                                  
    <jsp:include page="${jspRootPath}/includes/common/incPageFooterBlog.jsp" />
</html>

果然和我们猜想一样,这个页面是一个有占位符的文件,所以是模板文件,并且模板文件用的标签前缀都是 <decorator>,所以这个模板文件中有3个可插入内容的点,一个是<decorator:title/>,一个是<decorator:head/>,一个是<decorator:body/>, 并且查询相关文章可以知道,整合素文件的过程是从素文件中分别提取出<title>,<head><body> 元素并且插入到相应的位置,如果没有相应的内容则使用后面的default默认值。当然了,<decorator>标记还有其他的内容,我们这里不一一阐述。

当然了,国际化惯例,为了使用这个标记,在页首必须声明标记前缀。从这里可以看出来,这个前缀来自http://www.opensymphony.com/sitemesh/decorator这个标记库

然后我们去探讨模板和适用页面之间的映射关系了,常识告诉我们肯定是在xml文件中配置,我们很快找到了这个映射文件,WEB-INF/decorators.xml

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
<?xml version="1.0" encoding="ISO-8859-1"?>
<decorators defaultdir="/WEB-INF/decorators">
    <!-- Any urls that are excluded will never be decorated by Sitemesh -->
                                                                                                                                                                                                                                             
    <excludes>
        <pattern>/changepassword*</pattern>
        <pattern>/*Ajax</pattern>
        <pattern>/*ajax</pattern>
        <pattern>/image</pattern>
        <pattern>/checkout/*</pattern>
        <pattern>/admin/search/*</pattern>
        <pattern>/index</pattern>
    </excludes>
                                                                                                                                                                                                                                             
    <!-- blog -->
    <decorator name="blog" page="blog_main.jsp">
        <pattern>/blog/*</pattern>
    </decorator>
    <!-- main -->
    <decorator name="main" page="main.jsp">
        <pattern>/*</pattern>
    </decorator>
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
    <decorator name="none">
        <pattern>/index.jsp</pattern>
    </decorator>
</decorators>

果然和设想一样,我们在WEB-INF/decorators中定义的2个模板文件在这里都有定义,并且每个模板文件(对应某个装饰器)都有给定的<pattern>,表明此装饰器使用的URL集合,我们找到了刚才的blog_main.jsp这个装饰页面使用的集合是/blog/ 开头的任意url。

当然了, 这里还可以使用<exclude>来控制那些页面不受到装饰模板的控制。

也许你会问,我们这个定义文件是否一定要叫WEB-INF/decorators.xml呢?其实不一定的,默认是在WEB-INF下的decorators.xml,(约定优于配置) ,这个约定在sitemesh.jar中。如果你要显式定制它的位置的话,那么它在sitemesh.xml中配置了位置:

1
2
3
4
5
6
7
8
9
<sitemesh>
    <property name="decorators-file" value="/WEB-INF/decorators.xml"/>
    <excludes file="${decorators-file}"/>
    <page-parsers>
        <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
    </page-parsers>
    <decorator-mappers>
...
</sitemesh>

从上可以看出,用于装饰模板的文件是定义在/WEB-INF/decorators.xml中。

本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1332310,如需转载请自行联系原作者

Sitemesh 初探相关推荐

  1. 2021年大数据Flink(九):Flink原理初探

    Flink原理初探 Flink角色分工 在实际生产中,Flink 都是以集群在运行,在运行的过程中包含了两类进程. JobManager: 它扮演的是集群管理者的角色,负责调度任务.协调 checkp ...

  2. 从壹开始微服务 [ DDD ] 之一 ║ D3模式设计初探 与 我的计划书

    缘起 哈喽大家周四好!又是开心的一天,时间过的真快,我们的 <从壹开始 .net core 2.1 + vue 2.5 >前后端分离系列共 34 篇已经完结了,当然以后肯定还会有更新和修改 ...

  3. 经典算法研究系列:二、Dijkstra 算法初探

    经典算法研究系列:二.Dijkstra 算法初探  July   二零一一年一月 ====================== 本文主要参考:算法导论 第二版.维基百科. 写的不好之处,还望见谅. 本 ...

  4. SiteMesh介绍

    1. SiteMesh简介 SiteMesh是由一个基于Web页面布局.装饰以及与现存Web应用整合的框架.它能帮助我们在由大量页面构成的项目中创建一致的页面布局和外观,如一致的导航条,一致的bann ...

  5. las格式测井曲线_邹榕,等:顺北和托甫台区块奥陶系断裂结构单元测井响应特征初探...

    引用格式:邹榕,徐中祥,张晓明,等.顺北和托甫台区块奥陶系断裂结构单测井响应特征初探[J].油气藏评价与开发,2020,10(2):18-23.ZOUR, XU Z X, ZHANG X M, et ...

  6. 2018-4-15摘录笔记,《网络表征学习前沿与实践》 崔鹏以及《网络表征学习中的基本问题初探》 王啸 崔鹏 朱文武

    1.来源:<网络表征学习前沿与实践>  崔鹏 (1)随着数据的增加以及计算机计算速度的增加,想当然的以为速度快了,数据再多也是可以自己算的,但是若是数据之间存在着复杂的关系,那么处理一个样 ...

  7. python argparse_Python 命令行之旅:初探 argparse

    本文首发于 HelloGitHub 公众号,并发表于 Prodesire 博客. 前言 你是否好奇过在命令行中敲入一段命令后,它是如何被解析执行的?是否考虑过由自己实现一个命令行工具,帮你执行和处理任 ...

  8. HTML5+MUI+HBuilder 之初探情人

    07,08年那会儿正当Java火爆,C/C++仍是广泛运用的一门语言的时候,所以我的大学都献给了C/C++和Java.当诺基亚的倒闭成为按键机时代衰落的标志时,移动APP的开发也如破堤之洪.爆炸式的崛 ...

  9. 使用Mahout搭建推荐系统之入门篇3-Mahout源码初探

    2019独角兽企业重金招聘Python工程师标准>>> 用意: 希望了解Mahout中数据的存储方式, 它如何避免java object带来的冗余开销.学完知识,要进行些实战 去分析 ...

最新文章

  1. 圈钱的道路上廖翔从不缺席
  2. 洛谷P1027 Car的旅行路线 计算几何 图论最短路
  3. IntelliJ IDEA 14.0.2破解注册码文件(2015年06月08日)
  4. MYSQL连接一段时间不操作后出现异常的解决方案
  5. webrtc 泄漏真实 ip 地址
  6. python打包工具报错_Python打包发布神器—Pyinstaller
  7. wxWidgets:wxURI类用法
  8. Java黑皮书课后题第4章:*4.18(学生的专业和年级)编程一个程序,提示用户输入两个字符,显示这两个字符代表的专业以及年级,第一个字符表示专业,第二个是一个数字字符1、2、3、4,输出对应结果
  9. 【练习】使用事务控制语句
  10. java 不重启部署_编译Java类后不重启Tomcat有两种方式:热部署、热加载
  11. mint-ui 写一个下拉滑动选择,mt-popup和mt-picker结合使用
  12. 设计模式之禅--思维导图
  13. 谷歌眼镜Mirror app开发之简单新闻浏览页面
  14. 确保河道环境_开展河道整治 改善生态环境
  15. mysql启动命令指定data目录_CentOS 7下MySQL的data目录更改后,使用mysqld服务启动失败...
  16. 一篇文章教你如何使用makerfile
  17. matlab 离散点求导_Matlab的离散点曲线导数曲率数值模拟方法
  18. 北京联通 烽火光猫+烽火HG680 不拆机破解
  19. 二倍图css,二倍图/三倍图的分辨率问题
  20. 两台路由器直连服务器需要怎么配置,设置串联两台无线路由器的方法步骤

热门文章

  1. Java事务设计模式
  2. Ubuntu18.04  网卡配置
  3. bean覆盖 springboot_如何在@SpringBootTest中使用Mock覆盖bean?
  4. 白杨SEO:中小企业发广告去哪个平台?一般选择哪种推广方式方法比较好?
  5. 2022-2028全球与中国连续血糖监测系统市场现状及未来发展趋势
  6. Git之cherry-pick
  7. 用大白话解释“什么是ERP?” 看完这篇就全明白了
  8. 关于电路的竞争与冒险问题详解
  9. (一)Spring启示录
  10. 华为荣耀3c卡android界面,双卡四核5英寸屏 华为荣耀3C电信版评测