Tiles入门及项目实战
1.Apache Tiles™
Apache Tiles是一个模板布局框架。最初是为了简化Web应用界面开发,如今已不限于JavaEE Web环境。
Tiles允许开发人员定义页面片段,它们在运行时会组装成一个完整的页面。这些片段,或者叫“瓷砖”(tiles本意即瓷砖),被其他页面引入以减少公共元素的重复定义,或者嵌入另一个tiles以组成一系列可重用的模板。
2.关于复合视图模式(Composite View Pattern)
Composite View Pattern
不少网站都有这样的特点:大部分页面遵循着相同的结构和布局。Composite View Pattern就是这种情况的典型应用场景。请看下图,两个网页有着相似的结构,只是body部分随情况改变,然而这确实需要绘制两个页面,这和使用frameset刷新其中一个子frame是不同的。
Composite View Pattern与Decorator pattern
Tiles是一个Composite View框架,它允许在整个应用重用页面片段。另一种能实现相同效果的办法是使用Decorator pattern((页面)装饰模式),例如Sitemesh就是基于装饰模式的。不同于Composite
View创建模板并动态组装页面片段,Decorator pattern利用一个HTML页面添加各个(页眉、页脚、菜单...)部分以呈现界面。你可以通过下表看到他们之间的使用差别:
| 哪些方面 | Composite View | Decorator |
| 可重用性 | 页面的不同部分(模板和片段)能够在整个应用重用 | 每个装饰器都能被重用,但是同一时间装饰器本身只能应用于一个页面 |
| 配置简便性 | 每个页面都必须显式定义 | 装饰器甚至能够应用于整个应用 |
| 运行时配置 | 页面能在运行时配置、组装 | 由于页面装饰一次,没有此特性 |
| 性能 | 组装开销很低 | 被装饰的页面必须被解析 |
3.几个概念
Tiles实现了复合视图模式(Composite View Pattern),为了实现这个模式Tiles添加了几个自己的概念:Template(模板)、Attribute(属性)、Definition(定义)。
Template
即页面布局,页面的各个部分由Attribute填充。(Template可以没有Attribute)
举个栗子,考虑下图的经典风格布局:
一个模板(Template)页面的代码可能类似下面这样:
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<table>
<tr>
<td colspan="2">
<tiles:insertAttribute name="header" />
</td>
</tr>
<tr>
<td>
<tiles:insertAttribute name="menu" />
</td>
<td>
<tiles:insertAttribute name="body" />
</td>
</tr>
<tr>
<td colspan="2">
<tiles:insertAttribute name="footer" />
</td>
</tr>
</table>
Attribute
Attribute就是页面上那些待填充的空白部分,它允许以下三种类型:
● string:页面直接呈现的内容。
● template:一个可能包含Attribute的模板,如果包含则必须填充Attribute以呈现页面。
● definition:一个可重用的页面部分,其中部分或全部的Attribute已被填充。
Definition
Definition是最终要展现给用户的部分,其实就是一个Attribute完全或部分填充的Template。
● 如果Attribute已完全填充,它就可以展现给用户。
● 如果还有尚未填充的Attribute,这被称作抽象定义(abstract definition),它可以被其他Definition继承以实现布局复用,或者也可以在运行时填充这些Attribute。
就拿上面的经典布局风格举个栗子(注意页面中insertAttribute的name属性与definition中put-attribute的name属性的对应关系):
<definition name="myapp.homepage" template="/layouts/classic.jsp">
<put-attribute name="header" value="/tiles/banner.jsp" />
<put-attribute name="menu" value="/tiles/common_menu.jsp" />
<put-attribute name="body" value="/tiles/home_body.jsp" />
<put-attribute name="footer" value="/tiles/credits.jsp" />
</definition>
4.在maven中添加Tiles依赖(以Tiles 3.0.5版本为例)
Tiles是一个Web应用包,曾经和Struts捆绑使用,如今已独立出来,目前最常用的情形是基于servlet的web应用。
你需要具备以下环境才能保证Tiles正常使用:JDK1.6或更高版本,Servlet2.5
简单起见,仅仅你的pom.xml加入以下内容就可以使用Tiles的所有特性了(入门的话不需要再往下看配置了):
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-extras</artifactId>
<version>3.0.5</version>
</dependency>
如果你不打算使用所有特性,基本的仅支持servlet的依赖如下:
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>3.0.5</version>
</dependency>
如果你还想加入JSP支持,继续添加:
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.5</version>
</dependency>
5.SpringMVC集成Tiles
Spring 3.2.x支持2.1.2及以上版本的Tiles,如果你使用Spring 4请集成Tiles 3.0.x及更高版本。
配置
配置TilesConfigurer以加载Tiles定义文件
WebApplicationContext初始化时,下面的定义文件被加载并且定义工厂(DefinitionsFactory)被实例化。
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<!-- Tiles2:<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"> -->
<property name="definitions">
<list>
<!-- <value>classpath:tiles/tiles-template.xml</value> -->
<value>/WEB-INF/defs/general.xml</value>
<value>/WEB-INF/defs/widgets.xml</value>
<value>/WEB-INF/defs/administrator.xml</value>
<value>/WEB-INF/defs/customer.xml</value>
<value>/WEB-INF/defs/templates.xml</value>
</list>
</property>
</bean>
至此已经可以在Spring Web工程中作为view使用了,和使用Spring的其它视图技术一样,我们还需要一个视图解析器(ViewResolver)。我们可以使用支持解析多种视图的ResourceBundleViewResolver(参见:http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/view.html#view-tiles),简单起见,我们使用UrlBasedViewResolver:
<!-- 配置方式一(UrlBasedViewResolver将会实例化给定的viewClass) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
<!-- Tiles2:<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/> -->
</bean>
<!-- 配置方式二 -->
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
<!-- Tiles2:<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver"> -->
如果打算使用Tiles的高级特性,看这里!
如果你打算使用Tiles的某些高级特性,像运行时构建视图(Runtime Composition)、更复杂的通配符支持(Wildcard
support)之类,启用方式有两种:
方式一:springMVC集成Tiles3情形下很合适:
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/config/tiles.xml</value>
<value>/WEB-INF/config/tiles-adf.xml</value>
</list>
</property> <!-- Specify whether to apply Tiles 3.0's "complete-autoload" configuration. -->
<property name="completeAutoload" value="true" />
</bean>
方式二:在web.xml中配置监听器:
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
6.项目实战
SpringMVC整合Tiles3,基于Maven构建,Bootstarp做前台页面呈现尽管做的相对简陋。菜单可以切换两种布局方式(用继承以及覆盖解释如何换汤不换药),当然,还有点彩蛋 ==
下面的项目实战我们也用到了通配符以简化定义,在普通的springMVC集成Tiles工程里通配符的使用可能类似下面这样:
<definition name="tiles/*" extends="base.definition">
<!-- {1}:通配符方式简化定义 -->
<put-attribute name="content" value="/WEB-INF/views/{1}.jsp"/>
</definition>
然而,当我们用springMVC整合Tiles时在springMVC配置文件中启用了complete-autoload导致通配符的使用方式需要做些改进(配置监听器的方式不会出现此问题):
<definition name="WILDCARD:tiles/*" extends="base.definition">
<!-- {1}:通配符方式简化定义 -->
<put-attribute name="content" value="/WEB-INF/views/{1}.jsp"/>
</definition>
还有点说明
文章并没有解释Tiles的高级特性部分,但是部分应用已经体现在下面的项目中了,比如定义的继承、Runtime Composition、通配符、EL支持...
下载地址:tiles3-springmvc.rar
Tiles入门及项目实战的更多相关文章
- 移动端自动化测试Appium 从入门到项目实战Python版☝☝☝
移动端自动化测试Appium 从入门到项目实战Python版 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 说到APP自动化测试,Appium可是说是非常流 ...
- 移动端自动化测试appium 从入门到项目实战Python版✍✍✍
移动端自动化测试appium 从入门到项目实战Python版 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程 ...
- 移动端自动化测试Appium 从入门到项目实战Python版
移动端自动化测试Appium 从入门到项目实战Python版 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课 ...
- 数据量大了一定要分表,分库分表组件Sharding-JDBC入门与项目实战
最近项目中不少表的数据量越来越大,并且导致了一些数据库的性能问题.因此想借助一些分库分表的中间件,实现自动化分库分表实现.调研下来,发现Sharding-JDBC目前成熟度最高并且应用最广的Java分 ...
- 阿里分布式开源框架DUBBO 入门+ 进阶+ 项目实战视频教程
史诗级Java/JavaWeb学习资源免费分享 欢迎关注我的微信公众号:"Java面试通关手册"(坚持原创,分享各种Java学习资源,面试题,优质文章,以及企业级Java实战项目回 ...
- Python轻松入门到项目实战-实用教程
本课程完全基于Python3讲解,针对广大的Python爱好者与同学录制.通过本课程的学习,可以让同学们在学习Python的过程中少走弯路.整个课程以实例教学为核心,通过对大量丰富的经典实例的讲解.让 ...
- Linux运维企业架构项目实战系列
Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...
- VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战(原创)
VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战 1.给指定项目安装Newtonsoft.Json ,Version 4.5.11 PM> Install-Package Ne ...
- 微信小程序入门与实战 常用组件API开发技巧项目实战*全
第1章 什么是微信小程序? 第2章 小程序环境搭建与开发工具介绍 第3章 从一个简单的“欢迎“页面开始小程序之旅 第4章 第二个页面:新闻阅读列表 第5章 小程序的模板化与模块化 第6章 构建新闻详情 ...
随机推荐
- 今天犯的一个错误,导致method GET must not have a request body
事件经过: 1.在本地机器运行完全正常的程序,手动人工发包到测试环境上,后台日志频频报method GET must not have a request body. 2.使用postman发送pos ...
- Ubuntu16.04 Mysql
1.安装mysql root@ubuntu:~# sudo apt-get install mysql-server root@ubuntu:~# apt install mysql-client r ...
- gui编程实战——qq聊天界面1
public class testDemo_2 extends JFrame{ JTextArea jta=null; //多行文本框组件 JScrollPane jsp=null; //滚动文本框 ...
- PIC18F26K20
Clock Four Crystal modes, Two External clock modes, Two RC Oscillator, Internal oscillator, PLL
- [BeiJing2006]狼抓兔子 dijkstra+平面图最小割
一眼裸的最大流求最小割,然而数据范围过大,跑不下来. 我们可以将平面图转成对偶图,并进行连边. 这样,每条边的长度就对应原图中的割边长度. 起点到终点的最短路即为最小割. 别用SPFA,会死的很惨 C ...
- (四)React高级内容
1. React developertools安装及使用 2. PropTypes与DefaultProps 讲一下PropTypes, 先拿TodoItem来说: 从几种类型中选: 3 props ...
- Vue学习之v-if与v-show的区别
v-if和v-show具有类似的功能,不过v-if才是真正的条件渲染,他会根据表达式适当的销毁或重建元素及绑定事件或子组件.若表达式初始值为false,则一开始元素或组件不会渲染,只有当第一次为真时, ...
- input标签type为number时,输入小数,在Firefox浏览器上输入框标红的问题
问题一:firefox 下 默认情况 <input type="number"> 只允许输入整数,输入小数时会报错,输入框被标红 这时候可以添加参数 step=&q ...
- [ZJOI2015]幻想乡战略游戏(点分树)
题意自己看... 思路 没想到今(昨)天刷着刷着点分治的水题,就刷出来了一个点分树... 然后就疯狂地找题解,代码,最后终于把它给弄懂了. 点分树——动态点分治,对于此题来说,我们设u为当前的补给站位 ...
- 洛谷 P2183 巧克力
P2183 巧克力 题目描述 佳佳邀请了M个同学到家里玩.为了招待客人,她需要将巧克力分给她的好朋友们.她有N(1<=N<=5000)块巧克力,但是大小各不一样,第i块巧克力大小为为1*X ...