`

引用 活用SiteMesh,一个装饰器就可支撑整个网站结构

 
阅读更多
引用

wanglei19850713 的 活用SiteMesh,一个装饰器就可支撑整个网站结构

活用SiteMesh,一个装饰器就可支撑整个网站结构


在 寻求网站结构的高效统一上,SiteMesh通过Decorator的设计模式,十分利索地达到了目的。其设计思想是,用户发送request至服务器, 服务器根据此request生成动态数据,生成网页,准备返回给客户端。就在返回前,SiteMesh进行拦截,对此网页进行解析,将title、 body等部分拆解出来,套上模板后,再返回给客户端。由于SiteMesh在返回客户端的最后一步工作,此时的网页已经具备了标准的html网页格式, 因此SiteMesh只需解析标准的html网页,无需考虑各个Web应用是应用了JSP、ASP,还是Velocity技术,相当灵活。

一般情况下,我们在decorators.xml文件中定义一个模板main.jsp,来自动套用未加装饰的网页:

<decorators defaultdir="/decorators">
    <decorator name="main" page="main_decorator.jsp">
          <pattern>/*</pattern>
    </decorator>
</decorators>


main_decorator.jsp是默认的装饰器,其pattern应用于所有的网页。其典型的代码如下:


1: <%@page contentType="text/html"%>
2: <%@page pageEncoding="gb2312"%>
3: <%@taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
4: <%@taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%>
5: <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
6:
7: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
8:   "http://www.w3.org/TR/html4/loose.dtd">
9:    
10: <fmt:setBundle basename="AppResource" />
11:
12: <html>
13:    <head>
14:      <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
15:      <title><fmt:message key="webapp.name" /> - <decorator:title default="Welcome!" /></title>
16:      <link rel="stylesheet" href="<%=request.getContextPath()%>/css/w3c.css" type="text/css" />
17:      <decorator:head />
18:    </head>
19:    <body id="matrix">
20:      <script type="text/javascript">window.status = "正在加载: <decorator:title default="INTRANET" />...";</script>
21:      <div id="container">
22:        <script type="text/javascript">window.status = "正在加载: 页眉";</script>
23:        <div id='pageHeader'>
24:          <%@include file="/includes/header.jsp"%>
25:        </div>
26:        <div id="centralBody">
27:          <div id="mainbg">
28:            <script type="text/javascript">window.status = "正在加载: 页面内容";</script>
29:            <div id="mainContent">
30:              <decorator:body />
31:            </div>
32:            <script type="text/javascript">window.status = "正在加载: 右边导航栏";</script>
33:            <div id="sideBar">
34:              <page:applyDecorator page="/rootsidebar.jsp" name="sidebar" />
35:            </div>
36:          </div>
37:        </div>
38:        <script type="text/javascript">window.status = "正在加载: 页脚";</script>
39:        <div id="footer">
40:          <%@include file="/includes/footer.jsp"%>
41:        </div>
42:      </div>
43:      <script type="text/javascript">window.status = "完毕";</script>
44:    </body>
45: </html>

假设有一个未加装饰的网页index.jsp如下:

<%@page contentType="text/html; charset=gb2312"%>
<html>
    <head>
        <title>首页</title>
    </head>
    <body>
        <h2>Hello, World!</h2>
    </body>
</html>

当SiteMesh工作时,它会分解出title及body的内容,并将其分别通过<decorator:title>及<decorator:body>套用到默认的main.jsp上。

好,首页工作得很好,我们准备装饰第二个网页downlaod.jsp。此网页的内容如下:

<%@page contentType="text/html; charset=gb2312"%>
<html>
    <head>
        <title>下载页面</title>
    </head>
    <body>
        <h2>欢迎下载!</h2>
    </body>
</html>

我们发现,当main_decorator.jsp这个装饰器装饰此网页上时,title及body均没问题。但在第34行,作为下载页面的sidebar不应该是rootsidebar,而应是downloadsidebar,即第34行的代码应为:

34: <page:applyDecorator page="/downloadsidebar.jsp" name="sidebar" />

很显然,我们需要另外一个装饰器,于是我们将第34行改后另存为一个名为download_decorator.jsp的装饰器,还是存于/decorators下面。


相应地,在download.jsp的<title>此行上加上:

<meta name="decorator" content="download_decorator" />

SiteMesh将根据此元数据的指示,自动调用download_decorator.jsp的装饰器。

但观察两个装饰器,只有第34行不同。只因为一行不同而需要创建另一个装饰器,代价较高。而往下,每一个需要不同的sidebar的页面都必须另行 创建一个新装饰器。看来这种方式令人无法忍受。我们注意到,title、body与sidebar都是被装饰的部分,但title及body却可以不用修 改装饰器实现共享,而sidebar的装饰部分却不行。title及body均是由<decorator>标签来实现,而sidebar 由<page:applyDecorator>来实现。看来不同的结果就源自于这两个标签的不同之上。

我们来看SiteMesh后台的实现原理。SiteMesh在装饰网页时,先分解出index.jsp及download.jsp的title及 body,然后读取装饰器,遇到<decorator>标签时,换入title及body的内容。遇 到<page:applyDecorator>时,读取其page属性所指定的网页,然后应用名为sidebar的另一个装饰器来装饰 sidebar,装饰完后再将结果换进main_decorator。看来,两者的区别在于<decorator>所加工的素材是未装饰的网 页已经主动提供的,而因为我们不能主动提供素材给<page:applyDecorator>,因此main_decorator必须自己去 找。这就是它们的本质区别。

这使我们想起设计思想中的依赖注入模式。<decorator>就是一个setter, 而<page:applyDecorator>则是一个getter,因此它必须自己去寻找所需的素材。如果我们能根据依赖注入模式,为其注 入所需素材,那么,就像<decorator>一样,它也不需要再变了。

实现的思路是,download.jsp负责传递一个含有具体page文件名的参数给<page:applyDecorator>,然 后,<page:applyDecorator>将其值赋于page属性。对于download.jsp来讲,存放于参数的好地方是网页中 的<meta>部分。因此,在其<title>之上加上这一行:

<meta name="sidebar" content="/downloadsidebar.jsp" />

这样,<page:applyDecorator>就有机会读取此参数了。配合使用SiteMesh的另一个标签<decorator:usePage>,我们可以顺利地为page属性设定值。

<decorator:usePage id="myPage" />
<page:applyDecorator page='<%= myPage.getProperty("meta.sidebar") %>' name="sidebar" />

通过这种方法,将原来的由main_decorator主动索取sidebar文件名的方式,改为其被动地接收参数,然后由在各个页面中通过设定 meta name="sidebar"的方式,将sidebar文件名传入。从对象责任的角度来看,也正应页面才能知道其sidebar是什么。从而在 SiteMesh中成功地应用于依赖注入的模式。

这样,只需一个装饰器,就可以支撑整个网站的结构了。
分享到:
评论

相关推荐

    sitemesh装饰器入门

    当一个 Web 请求到达服务器时,Sitemesh 会拦截请求,检查是否需要应用装饰器。如果需要,它会将原始页面内容与装饰器模板结合,生成最终的 HTML 页面返回给客户端。这个过程涉及到两个主要的配置文件:`web.xml` 和...

    页面装饰器(sitemesh)实例源代码

    页面装饰器(Sitemesh)是一种广泛用于Web应用的开源框架,它的主要功能是提供页面布局和装饰功能,使得开发者可以方便地实现统一的页面头部、尾部、侧边栏等元素,从而提高网站的整体风格一致性。在本实例中,我们...

    SiteMesh教程.pdf

    SiteMesh是一种用于Java Web应用的装饰器设计模式框架,主要通过拦截Web页面请求,动态地将装饰页面如头部(header)、底部(footer)、样式表(stylesheet)和脚本文件(scripts)等页面元素与实际页面组合在一起,...

    sitemesh

    **Sitemesh** 是一个广泛使用的开源Web应用框架,它主要功能是提供页面布局和装饰功能,用于统一网站的外观和感觉。Sitemesh通过在Web应用中引入“母版”(Master Page)的概念,使得开发者可以轻松地创建一致性的...

    java sitemesh 页面框架

    Java Sitemesh是一个开源的页面布局和装饰框架,它的主要目标是帮助开发者统一网站的外观和感觉,提高代码复用性,并简化页面的复杂性。Sitemesh通过将页面分为内容区域和装饰模板来实现这一目标,使得开发者可以...

    sitemesh入门demo

    Sitemesh 提供了一种优雅的方式来组织和装饰Web页面,通过定义模板和装饰器,可以统一整个网站的头部、底部、侧边栏等元素,提高开发效率和代码复用性。 在"**sitemesh入门demo**"中,我们将学习如何设置和使用...

    sitemesh简单教程页面装配器

    当用户访问`index.jsp`时,Sitemesh会自动使用配置好的装饰器页面对其进行包装,从而呈现出一个完整的页面。 #### 三、装饰器(Decorator)概念及其优势 装饰器模式是一种常用的软件设计模式,用于动态地给一个...

    sitemesh框架简单例子

    它使用一种叫做装饰器(Decorator)的模板来包裹原始内容,从而在不影响原有页面结构的基础上添加额外的元素。装饰器通常包含页眉、页脚、导航栏等重复元素,而页面内容则作为被装饰的对象,被插入到装饰器的指定...

    SiteMesh2.3很全的一个资料

    SiteMesh 是一个开源的Web应用程序框架,用于帮助开发者在页面级别上实现页面布局和装饰功能。这个框架的主要目的是解决在大型网站中保持页面样式一致性的问题。SiteMesh 2.3 版本是其系列中的一个重要版本,包含了...

    SiteMesh

    SiteMesh的工作原理是基于过滤器(Filter)机制,当用户请求一个页面时,SiteMesh过滤器会捕获这个请求,然后将请求的页面内容与预先定义好的装饰模板进行合并,最终返回给浏览器展示。这样,开发者可以专注于编写...

    sitemesh教程

    装饰器通常包含一个头部、一个底部以及一个或多个“装饰区”(Decorated Areas),这些区域将被实际的页面内容替换。 - **定义装饰器**: - 在`decorators.xml`文件中定义装饰器: ```xml &lt;head&gt;&lt;![CDATA[ &lt;!...

    sitemesh-2.2.1.jar sitemesh-2.2.1.jar

    - **dom4j-1.6.1.jar**:这是一个Java XML处理库,Sitemesh可能用它来解析和操作XML文档,包括装饰器定义文件。 - **javacpp-1.3.2.jar**:这可能是JavaCPP库的一个版本,它提供了一个接口,可以直接在Java中调用C++...

    SiteMesh教程及SiteMesh官方文档翻译

    以上配置指定了装饰器页面所在的路径,并定义了一个名为“main”的装饰器,该装饰器默认会装饰Web应用根路径下的所有页面。 **第四步:创建装饰器页面** 接下来,需要创建装饰器页面本身,例如`/decorators/main....

    siteMesh demo+文档

    3. **定义装饰模板**:SiteMesh允许你创建一个或多个装饰模板,这些模板定义了页面的结构,如页眉、页脚、侧边栏等。你可以使用HTML或者JSP来编写模板。 4. **应用装饰**:通过在JSP页面中使用特殊的注解(例如`&lt;@...

    springMVC与sitemesh的结合

    Spring MVC 是一个强大的Java Web应用程序开发框架,由Spring.io团队维护,它提供了模型-视图-控制器(MVC)架构,使开发者能够更方便地构建可维护、可扩展的Web应用。而Sitemesh则是一个页面布局和装饰框架,主要...

    sitemesh2.5源码

    Sitemesh 是一个开源的网页布局和装饰框架,主要用于增强Web应用的外观一致性。Sitemesh2是其第二个主要版本,它提供了更加强大和灵活的功能来帮助开发者统一网站的页面布局。在这个项目中,我们可以深入研究其源码...

    sitemesh3-demo

    Sitemesh是一个开源的Java Web应用框架,主要用于增强网页的外观和结构,通过定义装饰模板,可以统一网站的头部、底部和侧边栏等元素,提高开发效率和代码复用性。 Sitemesh3是Sitemesh的第三个主要版本,相比之前...

    sitemesh 例子

    例如,一个简单的装饰器可能如下: ```html &lt;!DOCTYPE html&gt; ${page.title} ; charset=UTF-8"&gt; &lt;!-- 其他CSS和JavaScript引用 --&gt; &lt;!-- 网站头部内容 --&gt; ${page.content} &lt;!-- 网站底部内容 -...

    siteMesh框架demo

    当用户请求一个页面时,SiteMesh会捕获这个请求,然后将页面内容传递给预先定义好的装饰器进行包装,最后返回给浏览器,这样就实现了页面的统一风格。 首先,我们需要在项目中引入SiteMesh的依赖库。这通常通过...

Global site tag (gtag.js) - Google Analytics