Tiles是一个免费的开源模板Java应用程序的框架。基于复合模式简化的用户界面的构建。对于复杂的网站仍是最简单、最优雅的方式与任何MVC技术一起工作。Struts2对Tiles提供了支持,如今Tiles发展已有13个年头,成为Apache的一个独立项目,我们可以单独使用Tiles来构建用户界面布局。

Tiles项目:http://tiles.apache.org/index.html

Tiles的配置DTD定义:http://tiles.apache.org/framework/tiles-core/dtddoc/index.html

本文主要通过构建一个简单的页面布局来认识Apache Tiles3.x(由于Tiles2.x和Tiles3.x存在较大差异)。

1.准备工作

1.1安装Apache Tiles3.x依赖的Jar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-extras</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-servlet</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>3.0.5</version>
        </dependency>

注意:这里使用了Apache3.x完整包依赖。

1.2调试环境

安装jetty-maven-plugin来热部署web应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
        <finalName>tiles</finalName>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>7.1.6.v20100715</version>
                <configuration>
                    <scanIntervalSeconds>1</scanIntervalSeconds>
                    <reload>automatic</reload>
                    <webAppConfig>
                        <contextPath>/tiles</contextPath>
                    </webAppConfig>
                </configuration>
            </plugin>
        </plugins>
    </build>

注意:运行mvn jetty:run -Djetty.port=9999 命名,访问http://localhost:9999/tiles 需要额外在Maven的settings.xml文件的插件组中添加插件组标识。

1
2
3
4
5
6
7
<pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
    <pluginGroup>org.mortbay.jetty</pluginGroup>
  </pluginGroups>

1.3配置web.xml

在web.xml中添加Tiles监听器

1
2
3
<listener>
        <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
    </listener>

关于Tiles的监听器可以自定义实现,参见:http://tiles.apache.org/framework/config-reference.html

2.分析界面组成,构建布局文件

假设本案例中的页面构成如图:

分析界面布局,找不通用部分,特殊部分。 在webapp下创建layout文件夹放在布局文件,snippet文件夹放置公共部分。

通过分析,将布局切割为header,body,footer,并且将HTML页面中的meta,script公共部分抽取出来。

  • /snippet/meta.jsp

1
2
3
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  • /snippet/script.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<style>
div {
    width: 480px;
    height: 80px;
    background: silver;
}
 
#body {
    background: lime;
}
 
</style>
<script type="text/javascript">
    document.writeln("这句话是由JavaScript写入页面的。");
</script>
  • /snippet/header.jsp

1
2
3
4
5
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h3>
这是头部
</h3>
  • /snippet/footer.jsp

1
2
3
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h3>这是页脚</h3>
  • /snippet/index_body.jsp

1
2
3
4
5
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<pre>
    这是页面的主体部分
</pre>

通过上面的公共部分和主体,构建一个布局文件如下:

  • /layout/index_layout.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE html>
<html>
<head>
<tiles:insertAttribute name="meta" />
<title><tiles:insertAttribute name="title" /></title>
<tiles:insertAttribute name="script" />
</head>
<body>
    <div id="header">
        <tiles:insertAttribute name="header" />
    </div>
    <div id="body">
        <tiles:insertAttribute name="body" />
    </div>
    <div id="footer">
        <tiles:insertAttribute name="footer" />
    </div>
</body>
</html>

3.Tiles的复合布局定义

Tiles是通过在xml文件中配置definition进行页面公共部分的重用,页面布局的组合。

  • /WEB-INF/tiles-defs.xml 定义好公共部分之后,通过配置definition来组合页面布局。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" 
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<!-- Definitions for Tiles documentation -->
<tiles-definitions>
 
    <definition name="tiles.base.definition">
        <put-attribute name="meta" value="/snippet/meta.jsp" />
        <put-attribute name="script" value="/snippet/script.jsp" />
        <put-attribute name="header" value="/snippet/header.jsp" />
        <put-attribute name="footer" value="/snippet/footer.jsp" />
    </definition>
 
</tiles-definitions>

上面的definition可以说是抽象的,仅仅作为基本的定义抽取了界面中最通用的部分,而且并未指定具体的模版文件(布局文件)。下面通过继承tiles.base.definition来定一个tiles.index.definition其布局模版为/layout/index_layout.jsp。

1
2
3
4
<definition name="tiles.index.definition" extends="tiles.base.definition"
        template="/layout/index_layout.jsp">
        <put-attribute name="body" value="/snippet/index_body.jsp" />
    </definition>

上面定义tiles.index.definition,新增了body,其值为/snippet/index_body.jsp页面。

4.使用复合布局

到这里已经将页面的布局进行了分割,组合。现在应用definition来构建一个请求响应页面。

  • /example/index.jsp

1
2
3
4
5
6
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<tiles:insertDefinition name="tiles.index.definition">
    <tiles:putAttribute name="title" value="这是一个有Apache Tiles构建的页面布局." />
</tiles:insertDefinition>

5.启动服务器,访问/example/index.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
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html>
<head>
 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>这是一个有Apache Tiles构建的页面布局.</title>
 
<style>
div {
    width: 480px;
    height: 80px;
    background: silver;
}
 
#body {
    background: lime;
}
 
</style>
<script type="text/javascript">
    document.writeln("这句话是由JavaScript写入页面的。");
</script>
</head>
<body>
    <div id="header">
         
<h3>
这是头部
</h3>
    </div>
    <div id="body">
         
<pre>
    这是页面的主体部分
</pre>
    </div>
    <div id="footer">
         
<h3>这是页脚</h3>
    </div>
</body>
</html>

该例子中布局index_layout.jsp中body是可变的,title对一个不同的页面有不同的标题设置。在tiles-defx.xml的tiles.index.definition继承了tiles.base.definition,并且添加了其body页面,接着在插入tiles.index.definition的index.jsp页面添加了title。这样做达到的效果是整个站点的header,footer,meta,script抽取到了一个definition,然后通过继承的方式进行扩展,丰富不同的布局的页面组成元素,在具体的响应页面来定义专属该页面的内容。从而达到对页面的布局的控制,公共部分的复用的效果。

6.总结

本文仅仅是一个简单的示例,然而大部分内容被抽取公共部分占去,这样的结果并非意外,对于页面布局的划分,组合,重用才是使用Tiles之前最为繁重和复杂的工作,这些工作能够做的合理,优雅,配置definition自然就轻松多了。

http://aiilive.blog.51cto.com/1925756/1596059

接着上一篇:使用Apache Tiles3.x构建界面布局(一)继续构建页面布局。

上一篇示例中已经对页面的公共部分进行了抽取,创建了布局,并且将使用的布局应用的响应页面了。

1.定义definition来改变公共部分

现在有个新变化,响应页面的footer部分需要发生点变化,这个时候仍然可以通过继承的方式来配置一个definition。

  • /WEB-INF/tiles-defs.xml 中新增definition

1
2
3
4
<definition name="tiles.override.definition" extends="tiles.index.definition">
        <put-attribute name="footer"
            value="Copy Right &lt;a href='http://aiilive.blog.51cto.com'&gt;野马红尘&lt;/a&gt;"></put-attribute>
    </definition>

1.1创建响应页面/example/index_override.jsp

1
2
3
4
5
6
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<tiles:insertDefinition name="tiles.override.definition">
    <tiles:putAttribute name="title" value="这是一个有Apache Tiles构建的页面布局." />
</tiles:insertDefinition>

1.2访问:/tiles/example/index_override.jsp

注意:footer部分发生了改变,使用了tiles.override.definition的footer属性。

2.响应页面中定义body

  • /example/home.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<tiles:insertDefinition name="tiles.index.definition">
    <tiles:putAttribute name="title" value="HOME 页面." />
    <tiles:putAttribute name="body">
        <h3>这是HOME页面的body</h3>
        <ul>
            <li>Apache Tiles</li>
            <li>Sitemesh</li>
            <li>Smarty</li>
            <li>Freemarker</li>
            <li>Velocity</li>
        </ul>
    </tiles:putAttribute>
</tiles:insertDefinition>

访问:/tiles/example/home.jsp

3.通过Servlet来访问definition(tiles.index.definition),可编程式!

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
41
42
43
44
45
46
47
48
49
50
51
package secondriver.tiles.servlet;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.tiles.Attribute;
import org.apache.tiles.Definition;
import org.apache.tiles.TilesContainer;
import org.apache.tiles.access.TilesAccess;
import org.apache.tiles.request.ApplicationContext;
import org.apache.tiles.request.Request;
import org.apache.tiles.request.servlet.ServletRequest;
import org.apache.tiles.request.servlet.ServletUtil;
 
public class TilesServlet extends HttpServlet {
 
    private static final long serialVersionUID = 2721434552222217027L;
 
    @Override
    protected void service(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
 
        ApplicationContext applicationContext = ServletUtil
                .getApplicationContext(getServletContext());
 
        TilesContainer container = TilesAccess.getContainer(applicationContext);
        Request currentRequest = new ServletRequest(applicationContext,
                request, response);
 
        Definition definition = container.getDefinition(
                "tiles.index.definition", currentRequest);
        definition.putAttribute("title"new Attribute("通过servlet访问"));
        definition.putAttribute("body"new Attribute(
                "这是通过Servlet处理后的definition."));
        container.render(definition, currentRequest);
 
        /**
         * 不需要处理的时候可以直接使用definition的name
         
         * tiles.index.definition没有定义title属性
         
         * 而template文件(布局)中用到所以需要在Servlet中进行添加
         */
        // container.render("tiles.index.definition", currentRequest);
 
    }
}

访问:/tiles/tilesservlet

注意:

  • 这里使用了Servlet需要在web.xml中增加Servlet的配置

1
2
3
4
5
6
7
8
<servlet>
        <servlet-name>tilesservlet</servlet-name>
        <servlet-class>secondriver.tiles.servlet.TilesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>tilesservlet</servlet-name>
        <url-pattern>/tilesservlet</url-pattern>
    </servlet-mapping>
  • 在pom.xml中添加servlet-api:

1
2
3
4
5
<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

4.通过标签在响应页面上配置definition,并插入到页面中

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
 
<tiles:definition name="tiles.runtime.definiation"
    template="/layout/index_layout.jsp" extends="tiles.base.definition">
    <tiles:putAttribute name="title" value="通过标签配置 definition." />
    <tiles:putAttribute name="body">
        通过tiles标签配置的运行时definition
    </tiles:putAttribute>
</tiles:definition>
 
<tiles:insertDefinition name="tiles.runtime.definiation"></tiles:insertDefinition>

访问:/tiles/example/runtime.jsp

本文通过多种方式展示了Tiles的使用和其灵活性。另外Tiles还可以和Freemarker,Velocity,Spring,Struts等多种框架集成使用。

具体可以参考官方文档:http://tiles.apache.org/framework/whats-new.html。

另外更多的示例:http://tiles.apache.org/download.html

http://aiilive.blog.51cto.com/1925756/1596069

使用Apache Tiles3.x构建界面布局的更多相关文章

  1. 使用 Apache Tiles 3 构建页面布局

    参考博客:http://aiilive.blog.51cto.com/1925756/1596059Apache Tiles是一个JavaEE应用的页面布局框架.Tiles框架提供了一种模板机制,可以 ...

  2. 微信js框架第二篇(创建完整界面布局)

    接着昨天的继续谈关于微信新出的这个js框架,今天主要谈一个页面的创建到布局的详细步骤. 一.创建一个完整页面       页面你可以创建在项目的任何节点,只要你在入口文件正确引入创建该页面的路径就可使 ...

  3. 2013 duilib入门简明教程 -- 界面布局(9)

        上一个教程实现的标题栏代码中,并没有看到处理自适应窗口大小的代码,但是窗口大小变化后,按钮的位置会跟着变化,这是因为我们将按钮放到了HorizontalLayout.VerticalLayou ...

  4. php创建新用户注册界面布局实例

    php创建新用户注册界面布局实例 <!DOCTYPE> <html> <head> <title>Load page</title> < ...

  5. WPF基础知识、界面布局及控件Binding(转)

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  6. Unity 编辑器的 界面布局 保存方法

    在软件界面的右上角(关闭按钮的下方),点击  layout  (界面)的下拉箭头. 弹出选项中的 save layout....(保存界面选项),输入命名,就可以生成这个界面的布局.  (软件本身也有 ...

  7. ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

    本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...

  8. iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局

    iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文 ...

  9. UWP开发入门(二十)——键盘弹起时变更界面布局

    UWP APP在键盘弹起或隐藏时,并不会自动处理界面布局.有时会出现键盘遮挡了下一个需要填写的文本框,或是下一步按钮的情况.本篇我们以登录界面做例子,用一种巧妙简单的方式在键盘弹起和隐藏时更改界面的布 ...

随机推荐

  1. SpringBoot 使用yml配置 mybatis+pagehelper+druid+freemarker实例

    SpringBoot 使用yml配置 mybatis+pagehelper+druid+freemarker实例 这是一个简单的SpringBoot整合实例 这里是项目的结构目录 首先是pom.xml ...

  2. SpringBoot application.yml logback.xml,多环境配置,支持 java -jar --spring.profiles.active(转)

    趁今天有时间整理了一下 启动命令为 //开发环境 java -jar app.jar --spring.profiles.active=dev--server.port=8060 //测试环境 jav ...

  3. [Nuxt] Use Vuex Actions to Delete Data from APIs in Nuxt and Vue.js

    You'll begin to notice as you build out your actions in Vuex, many of them will look quite similar. ...

  4. [RxJS] Multicasting shortcuts: publish() and variants

    Because using multicast with a new Subject is such a common pattern, there is a shortcut in RxJS for ...

  5. 自定义 matplotlib 设置

    Customizing plots with style sheets import matplotlib as mpl 查看配置文件所在的目录:mpl.get_configdir() 1. 自定义 ...

  6. JobService和JobScheduler机制在Android5.0以上保活

    JobService和JobScheduler机制在Android5.0以上保活 我们知道在Android5.0之前,Android源代码还是有不小漏洞的,导致非常多不光明的手段来进行++保活++.但 ...

  7. 从0開始学习 GitHub 系列之「07.GitHub 常见的几种操作」

    之前写了一个 GitHub 系列,反响非常不错,突然发现居然还落下点东西没写,前段时间 GitHub 也改版了,借此机会补充下. 我们都说开源社区最大的魅力是人人多能够參与进去,发挥众人的力量,让一个 ...

  8. 为什么位运算可以实现加法(1、 不考虑进位的情况下位运算符中的异或^可以表示+号)(2、 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3、位运算不仅可以做加法,还可以做其它的乘法减法等:计算机本质是二进制运算)

    为什么位运算可以实现加法(1. 不考虑进位的情况下位运算符中的异或^可以表示+号)(2. 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3.位运算不仅可以做加法,还 ...

  9. Activity 调用Service的方法

    一般来说,Activity调用Service 分为两种:进程内调用和进程间调用.进程内调用时比较常用的一种,在进程内调用中我们常常使用的是bindService来启动Service(关于这种启动方式的 ...

  10. Seagate-保修验证(za25shrx)

    保修验证 http://support.seagate.com/customer/zh-CN/warranty_validation.jsp   Seagate   保修验证    End User  ...