SiteMesh

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標籤的一個翻版。其實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.ActionContextCleanUp過濾器之後,org.apache.struts2.dispatcher.FilterDispatcher過濾器之前,否則會有問題;

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

<%@ page language="java" pageEncoding="UTF-8"%>
<%@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: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系統頁面的一種方案。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章