Sitemesh 初探

简介:

引入:

最近在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的页面文件,所以我们找到了这些文件:

112957942.png

显然,在他们的项目中,这些模板文件是放在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。

114625178.png

当然了, 这里还可以使用<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,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
开发框架 Java .NET
Sitemesh3使用及配置
Sitemesh3使用及配置
|
7月前
|
Java Spring
15dwr - DWR 与 Spring整合
15dwr - DWR 与 Spring整合
26 0
|
7月前
|
Java PHP
17dwr - DWR 与 Struts整合
17dwr - DWR 与 Struts整合
15 0
|
6月前
|
开发框架 Java .NET
SiteMesh JSP布局框架介绍
SiteMesh JSP布局框架介绍
|
7月前
|
前端开发 JavaScript Java
20dwr - DWR 与 WebWork整合
20dwr - DWR 与 WebWork整合
23 0
|
7月前
|
缓存 JavaScript 前端开发
14dwr - DWR 与 Servlet整合
14dwr - DWR 与 Servlet整合
23 0
|
Java 数据安全/隐私保护
|
XML Java 数据格式