Tiles & SiteMesh
这两天在给公司的新项目搭框架,在配tiles框架的时候发现一个小问题:
比如开发团队一共5人,每人10个页面,如果按照简单的tiles框架配置方法,每个<definition/>中都会产生很多重复 的<put name="top" value="xxx.jsp"/>代码,导致tiles-defs.xml文件不段的膨胀.
仔细想了想tiles框架的原理,如果tiles支持嵌套功能的话,虽然tiles-defs.xml文件中的<definition/>个数没办法减少,但
每个<definition/>中的<put/>是完全可以精简的.即需要改变哪个页面就只配置哪个页面;
查了一下struts的文档,虽然没找到tiles框架的嵌套功能,却找到了组合和扩展(我喜欢叫它继承),同样能解决问题!
下面我简单介绍一下它们各自的用法:(页面布局见下图)

一,Tiles组件的模板
这里我们需要设置两个layout模板,分别为parent_layout.jsp和child_layout.jsp
parent_layout.jsp
<body>
<div>
<!--顶部菜单区域-->
<tiles:insert attribute="top" />
<!--左边竖导航-->
<tiles:insert attribute="left" />
<!--右边主内容区域-->
<tiles:insert attribute="child" />
<!--底步区域-->
<tiles:insert attribute="foot" />
</div>
</body>
child_layout.jsp
<body>
<div>
<!--右边主内容的tab区域-->
<tiles:insert attribute="tab" />
<!--右边主内容的content区域-->
<tiles:insert attribute="content" />
</div>
</body>
二,Tiles组件的组合
根据以上模板的定义,在tiles-defs.xml文件中就可以这样写来实现Tiles的组合了:
<definition name="parent"path="/parent_layout.jsp">
<put name="top" value="/top.jsp" />
<put name="left" value="/left.jsp" />
<put name="child" value="child" type="definition"/>
<put name="foot" value="/foot.jsp" />
</definition>
// 子级tiles配置
<definition name="child"path="/child_layout.jsp">
<put name="tab" value="/tab.jsp" />
<put name="content" value="/content.jsp" />
</definition>
三,Tiles组件的扩展(继承)
这里需要对以上的parent_layout模板做一些修改,并且不需要使用child_layout
修改后的parent_layout.jsp
<body>
<div>
<!--顶部区域-->
<tiles:insert attribute="top" />
<!--左边竖导航-->
<tiles:insert attribute="left" />
<!--右边主内容区域-->
<tiles:insert attribute="tab" />
<tiles:insert attribute="content" />
<!--底部区域-->
<tiles:insert attribute="foot" />
</div>
</body>
改完模板文件,下来该进行tiles的配置了;
<definition name="parent" path="/parent_layout.jsp">
<put name="top" value="/top.jsp" />
<put name="left" value="/left.jsp" />
<put name="tab" value="/tab.jsp" />
<put name="content" value="" />
<put name="foot" value="/foot.jsp" />
</definition>
<definition name="child" extends="parent">
<put name="content" value="/content.jsp" />
</definition>
如上所示,大家在开发中,每个页面只需要配置子级tiles的content.jsp就ok!
---------------------------------------------------------------------------------------------------------------
一、SiteMesh项目简介
OS(OpenSymphony)的SiteMesh是一个用来在JSP中实现页面布局和装饰(layout and decoration)
的框架组件,能够帮助网站开发人员较容易实现页面中动态内容和静态装饰外观的分离。
Sitemesh是由一个基于Web页面布局、装饰以及与现存Web应用整合的框架。它能帮助我们在由大
量页面构成的项目中创建一致的页面布局和外观,如一致的导航条,一致的banner,一致的版权,等等。
它不仅仅能处理动态的内容,如jsp,php,asp等产生的内容,它也能处理静态的内容,如htm的内容,
使得它的内容也符合你的页面结构的要求。甚至于它能将HTML文件象include那样将该文件作为一个面板
的形式嵌入到别的文件中去。所有的这些,都是GOF的Decorator模式的最生动的实现。尽管它是由java语言来实现的,但它能与其他Web应用很好地集成。
官方:http://www.opensymphony.com/sitemesh/
下载地址:http://www.opensymphony.com/sitemesh/download.action 目前的最新版本是Version 2.3;
二、为什么要使用SiteMesh?
我们的团队开发J2EE应用的时候,经常会碰到一个比较头疼的问题:
由于Web页面是由不同的人所开发,所以开发出来的界面通常是千奇百怪,通常让项目管理人员苦笑不得。
而实际上,任何一个项目都会要求界面的统一风格和美观,既然风格统一,那就说明UI层肯定有很多可以抽出来
共用的静态或动态部分;如何整合这些通用的静态或动态UI呢?Apache Tiles框架站了出来很好的解决了这一问题,
再加上他与struts的完美集成,导致大小项目都把他作为UI层的首选框架,
但是:
Tiles确实有着它很多的不足之处,下文我会介绍,本文想说的是,除了Apache Tiles框架,其实我们还有更好的解
决方案,那就是:SiteMesh;
本文
介绍了一个基于Web页面的布局、装饰以及应用整合的框架Sitemesh,它能帮助你为你的应用创建一致的外观,
很好的取代Apache Tiles;
三、SiteMesh VS Apache Tiles
用过struts的朋友应该对Apache Tiles的不会陌生,我曾经有一篇文章介绍过struts中tiles框架的组合与继承,
现在怎么看怎么觉得复杂;
从使用角度来看,Tiles似乎是Sitemesh标签<page:applyDecorator>的一个翻版。其实sitemesh最强的
一个特性是sitemesh将decorator模式用在过滤器上。任何需要被装饰的页面都不知道它要被谁装饰,所以它就
可以用来装璜来自php、asp、CGI等产生的页面了。你可以定义若干个装饰器,根据参数动态地选择装饰器,
产生动态的外观以满足你的需求。它也有一套功能强大的属性体系,它能帮助你构建功能强大而灵活的装饰器。
相比较而言,在这方面Tiles就逊色许多。
个人觉得在团队开发里面,Apache Tiles框架会导致所有人不仅仅要了解并且清楚Apache Tiles的存在,
并且要特别熟悉每一个Tiles layout模板的作用,否则就可能出现用错模板的情况;除此之外,每个人涉及到
的所有WEB页面都需要去配置文件里面逐个配置,不仅麻烦出错的几率还高;
而以上所有的不足都是SiteMesh所不存在的;
四、SiteMesh的基本原理
一个请求到服务器后,如果该请求需要sitemesh装饰,服务器先解释被请求的资源,然后根据配置文件
获得用于该请求的装饰器,最后用装饰器装饰被请求资源,将结果一同返回给客户端浏览器。
五、如何使用SiteMesh
这里以struts2+spring2+hibernate3构架的系统为例
1、下载SiteMesh
下载地址:http://www.opensymphony.com/sitemesh/download.action 目前的最新版本是Version 2.3;
2、在工程中引入SiteMesh的必要jar包,和struts2-sitemesh-plugin-2.0.8.jar;
3、修改你的web.xml,在里面加入sitemesh的过滤器,示例代码如下:
<!-- sitemesh配置 -->
<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>注意过滤器的位置:应该在struts2的org.apache.struts2.dispatcher.FilterDispatcher过滤器之前 org.apache.struts2.dispatcher.ActionContextCleanUp过滤器之后,否则会有问题;
4、在下载的SiteMesh包中找到sitemesh.xml,(/sitemesh-2.3/src/example-webapp/WEB-INF目录下就有)
将其拷贝到/WEB-INF目录下;
5、在sitemesh.xml文件中有一个property结点(如下),该结点指定了decorators.xml在工程中的位置,让sitemesh.xml能找到他;
按照此路径新建decorators.xml文件,当然这个路径你可以任意改变,只要property结点的value值与其匹配就行;
<property name="decorators-file" value="/WEB-INF/sitemesh/decorators.xml"/>6、在WebRoot目录下新建decorators目录,并在该目录下新建一个模板jsp,根据具体项目风格编辑该模板,
如下示例:我的模板:main.jsp
<%@taglib prefix="decorator"
uri="http://www.opensymphony.com/sitemesh/decorator"%>
<%@taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
%>
<html>
<head>
<title><decorator:title default="kangxm test" />
</title>
<!-- 页面Head由引用模板的子页面来替换 -->
<decorator:head />
</head>
<body id="page-home">
<div id="page-total">
<div id="page-header">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<div class="topFunc">
我的账户
|
退出
</div>
</td>
</tr>
</table>
</div>
</div>
<!-- end header -->
<!-- Menu Tag begin -->
<div id="page-menu" style="margin-top: 8px; margin-bottom: 8px;">
<div>
这里放菜单
</div>
</div>
<!-- Menu Tag end -->
<div id="page-content" class="clearfix">
<center>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<decorator:body /><!-- 这里的内容由引用模板的子页面来替换 -->
</td>
</tr>
</table>
</center>
</div>
<!-- end content -->
<div id="page-footer" class="clearfix">
这里放页面底部
<!-- end footer -->
</div>
<!-- end page -->
</body>
</html>
这就是个简单的模板,页面的头和脚都由模板里的静态HTML决定了,主页面区域用的是<decorator:body />标签;
也就是说凡是能进入过滤器的请求生成的页面都会默认加上模板上的头和脚,然后页面自身的内容将自动放到<decorator:body />标签所在位置;
<decorator:title default="Welcome to test sitemesh!" />:读取被装饰页面的标题,并给出了默认标题。
<decorator:head />:读取被装饰页面的<head>中的内容;
<decorator:body />:读取被装饰页面的<body>中的内容;
7、说到这里大家就要想了,那如果某个特殊的需求请求路径在过滤器的范围内,但又不想使用模板怎么办?
你总不能这么不讲道理吧!
大家放心吧,SiteMesh早就考虑到这一点了,上面第5步说道的decorators.xml这个时候就起到作用了!
下面是我的decorators.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<decorators defaultdir="/decorators">
<!-- Any urls that are excluded will never be decorated by Sitemesh -->
<excludes>
<pattern>/index.jsp*</pattern><pattern>/login/*</pattern>
</excludes>
<decorator name="main" page="main.jsp">
<pattern>/*</pattern>
</decorator>
</decorators>decorators.xml有两个主要的结点:
decorator结点指定了模板的位置和文件名,通过pattern来指定哪些路径引用哪个模板
excludes结点则指定了哪些路径的请求不使用任何模板
如上面代码,/index.jsp和凡是以/login/开头的请求路径一律不使用模板;
另外还有一点要注意的是:decorators结点的defaultdir属性指定了模板文件存放的目录;
六、实战感受
刚刚做完一个用到sitemesh的项目,跟以前用tiles框架相比,最大的感受就是简单,系统设计阶段
就把模板文件和sitemesh框架搭好了!哪些页面使用框架哪些不使用,全部都通过UI Demo很快就定义出来了;
在接下来的开发中所有成员几乎感受不到sitemesh的存在,各自仅仅关心自己的模块功能实现;
七、总结
使用sitemesh给我们带来的是不仅仅是页面结构问题,它的出现让我们有更多的时间去关注底层业务
逻辑,而不是整个页面的风格和结构。它让我们摆脱了大量用include方式复用页面尴尬局面,也避免了tiles
框架在团队开发中的复杂度,它还提供了很大的灵活性以及给我们提供了整合异构Web系统页面的一种方案。
Tiles & SiteMesh的更多相关文章
- [页面模板框架对比] Apache Tiles VS Sitemesh
1. 原理对比 (1) Apache Tiles 顾名思义,Tile是瓷砖的意思,也就是说一个网页是由多个Tile组成的. 用户通过访问一个页面的Apache Tiles定义名,就可以访问一个由定义文 ...
- SiteMesh:一个优于Apache Tiles的Web页面布局、装饰框架
一.SiteMesh项目简介 OS(OpenSymphony)的SiteMesh是一个用来在JSP中实现页面布局和装饰(layout and decoration)的框架组件,能够帮助网站开发人员较容 ...
- apache tiles 页面模板的使用
jar包maven <!-- Tiles 模板--> <dependency> <groupId>org.apache.tiles</groupId> ...
- J2EE sitemesh使用
maven包含sitemesh: <dependency> <groupId>opensymphony</groupId> <artifactId>si ...
- Sitemesh 3 的使用及配置
1 . Sitemesh 3 简介 Sitemesh 是一个网页布局和修饰的框架,基于 Servlet 中的 Filter,类似于 ASP.NET 中的‘母版页’技术.参考:百度百科,相关类似技术:A ...
- Sitemesh 3
Sitemesh 3 的使用及配置(收藏自:http://www.cnblogs.com/luotaoyeah/p/3776879.html) 1 . Sitemesh 3 简介 Sitemesh 是 ...
- SiteMesh入门(1-1)SiteMesh是什么?
1.问题的提出 在开发Web 应用时,Web页面可能由不同的人参与开发,因此开发出来的界面通常千奇百怪.五花八门,风格难以保持一致. 为了统一界面的风格,Struts 框架提供了一个标签库Tiles ...
- SiteMesh的使用--笔记
本博客是自己在学习和工作途中的积累与总结,仅供自己参考,也欢迎大家转载,转载时请注明出处. http://www.cnblogs.com/king-xg/p/6472659.html Sitemesh ...
- Tiles入门及项目实战
1.Apache Tiles™ Apache Tiles是一个模板布局框架.最初是为了简化Web应用界面开发,如今已不限于JavaEE Web环境. Tiles允许开发人员定义页面片段,它们在运行时会 ...
随机推荐
- 5_STL设计理念_迭代器
他山之石,可以攻玉. http://blog.csdn.net/jxh_123/article/details/30793397?utm_source=tuicool&utm_medium=r ...
- spring中schedule注解的使用
我们使用spring的注解 @Scheduled 执行定时任务 创建spring-task.xml 文件 <!---加入:xmlns:task="http://www.springfr ...
- 关于WPF中ItemsControl系列控件中Item不能继承父级的DataContext的解决办法
WPF中所有的集合类控件,子项都不能继承父级的DataContext,需要手动将绑定的数据源指向到父级控件才可以. <DataGridTemplateColumn Header="操作 ...
- <构建之法> 第四章 结对 读后感
粗读 第四章主要讲的是关于结对合作的事项.大多数的软件开发都是团体性的,而合作的最小单位也就是两个人,这也是软件开发中的最佳实践.而结对中,我们能够更好的编写我们的代码,能够少一些担心,对自己的代码也 ...
- [Android Tips] 7. 以调试模式启动应用
adb shell am set-debug-app -w {package_name}
- Maven聚合与继承的实例讲解(二)
继续上一节讲Maven的内容,我们这个节继续讲Maven继承和聚合的其他内容. 现在我们新建一个实例来测试Maven有关于聚合的部分 测试开始 一.建立以pom为packaging的项目 ...
- 匈牙利命名法、骆驼命名法、帕斯卡(pascal)命名法
(2008-05-24 13:37:55) 转载▼ 标签: 杂谈 分类: 编程杂文 一.匈牙利命名法: 广泛应用于象Microsoft Windows这样的环境中. Windows 编 ...
- JS实时数据运算
应朋友需要制作的一个小页面 <script type="text/javascript"> function cal(ida,idb,idc,idd) { var nu ...
- Extract Stylish styles and save as JSON format
Introduction Stylish is a easy browser extension/plugin for users to customizing the web page stylin ...
- Ugly Number II
注意负数,所以要使用long,而不能用int 详细解释 请参见http://www.cnblogs.com/julie-yang/p/5147460.html #include<vector&g ...