乐者为王

Do one thing, and do it well.

使用SiteMesh做网页布局

SiteMesh是一个基于GoF的Decorator模式,用于页面布局的框架。能帮助我们在由大量页面构成的项目中创建一致的页面布局和外观。

这里我们将会把它整合到JBookShelf里去。要和Struts 2整合,先在pom.xml添加以下插件,该插件会将依赖的SiteMesh也一并包含到项目中。

1
2
3
4
5
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-sitemesh-plugin</artifactId>
    <version>2.3.12</version>
</dependency>

将web.xml配置中原来的

1
2
3
4
5
6
7
8
9
10
11
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

改成

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
<filter>
    <filter-name>struts-prepare</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
</filter>

<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>

<filter>
    <filter-name>struts-execute</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts-prepare</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>struts-execute</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这里要注意过滤器的位置。SiteMesh过滤器必须在StrutsPrepareFilter之后和StrutsExecuteFilter之前,否则在SiteMesh的修饰器页面中将访问不到ActionContext。这是因为Struts 2的所有值是保存在Stack Context或者ValueStack中的。默认情况下,某个过滤器一旦访问了该Stack Context或ValueStack,里面对应的值会被清洗掉。如果先使用Struts 2的StrutsPrepareAndExecuteFilter来过滤用户请求,则SiteMesh的过滤器将无法取得Stack Context或者ValueStack中的数据。为了解决这个问题,Struts 2提供了StrutsPrepareFilter和StrutsExecuteFilter类(在2.1.3版本前是ActionContextCleanUp和FilterDispatcher),通过它们协同来确保SiteMesh正常工作。

在WEB-INF下添加decorators.xml文档:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<decorators defaultdir="/layouts">
    <excludes>
        <pattern>/stylesheets/*</pattern>
        <pattern>/javascripts/*</pattern>
        <pattern>/images/*</pattern>
    </excludes>

    <decorator name="application" page="application.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

stylesheets、javascripts、images目录下的内容是不需要被修饰的,可以把它们放到execludes块中排除掉。

新建/layouts/application.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
<%@ taglib uri="/struts-tags" prefix="s" %>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title><decorator:title default="JBookShelf" /></title>
    <decorator:head />
</head>

<body>
    <div>
        <s:if test="#session.user_session_key != null">
        <s:a action="listBook">All Books</s:a>
        Welcome, you have logined.
        <s:a action="logout">Logout</s:a>
        </s:if>
        <s:else>
        <s:a action="login!input">Login</s:a> |
        <s:a action="register!input">Register</s:a>
        </s:else>
    </div>
    <hr />
    <div>Navigation</div>
    <hr />
    <decorator:body />
    <hr />
    <div>Footer</div>
</body>
</html>

代码下载:https://github.com/dohkoos/JBookShelf

Comments