http://www.iocblog.net/static/2007/569.html
注:sitemesh,一個(gè)不錯(cuò)的tiles替代方案,比tiles做的更漂亮優(yōu)雅。本文是sitemesh官方推薦的入門文檔,本來想自己翻譯的,突然發(fā)現(xiàn)有人先行一步了,就轉(zhuǎn)過來看吧。
以前我通常使用舊式的方法來建立自己的web應(yīng)用:手工排版,仔細(xì)使用每一個(gè)字節(jié)使其工作在Unicode下,同時(shí)使用make文件來適應(yīng)不同的CPU……
或許現(xiàn)在我們可以換一種方式。
盡管我從沒有感覺到需要使用assembly (CISC or RISC)來建立web應(yīng)用,但也會(huì)偶爾覺得我的開發(fā)伙伴的工作相當(dāng)繁瑣。特別是我發(fā)現(xiàn)很多的開發(fā)者在痛苦的尋求一種比較好的方式來控制web應(yīng)用的基本模塊:例如那些頁頭、頁尾、導(dǎo)航欄、打印頁面、手持設(shè)備的輕量級頁面,以及其他更多的問題。到了最后,令人驚異的是大部分人都采用了落后的 includes和復(fù)制粘貼方式。
根據(jù)經(jīng)驗(yàn),我可以采用在 java.net 上開源的servlet 過濾器 SiteMeshn 來簡單明了并優(yōu)雅的解決這些問題。作為一種替代新的templating語言(XSLT)或部署您的頁面到新的系統(tǒng)的解決方法,應(yīng)用SiteMesh可以相當(dāng)容易處理你的頁面,這一切只需要普通的HTML,JSP,servlet(包括Struts),以及其他常用的技術(shù)。
工作原理
SiteMesh 利用了一種很少人知道的servlet規(guī)范實(shí)現(xiàn)了一種頁面過濾器。設(shè)想一下,現(xiàn)在有一個(gè)簡單的jsp頁面用來返回當(dāng)前的日期和時(shí)間。通常這個(gè)頁面請求來到應(yīng)用服務(wù)器,頁面被處理,最后處理結(jié)果返回到web瀏覽器。SiteMesh作為一個(gè)頁面過濾器,在頁面被處理之后,返回web瀏覽器之前,對頁面做了一些附加的操作。這個(gè)變化簡單描述為圖一和圖二所示的附加步驟。
圖一:普通頁面處理情況
圖二:SiteMesh對頁面處理情況
現(xiàn)在看一個(gè)簡單的例子。
<html>
<head>
<title>Simple Document</title>
</head>
<body>
Hello World! <br />
<%= 1+1 %>
</body>
</html>
你會(huì)發(fā)現(xiàn)這個(gè)頁面有一個(gè)title和body(類似普通的HTML頁面)。你也會(huì)發(fā)現(xiàn)一小段JSP代碼——它將會(huì)如同你期望的那樣被處理。同時(shí)你可以使用任何你想使用的JSP語法和特性來替換這一小段代碼。
現(xiàn)在來看一個(gè)簡單的SiteMesh "裝飾(decorator)"頁面。列表2顯示了一個(gè)被SiteMesh調(diào)用的JSP頁面。
<%@ taglib uri="sitemesh-decorator"
prefix="decorator" %>
<html>
<head>
<title>
My Site - <decorator:title default="Welcome!" />
</title>
<decorator:head />
</head>
<body>
<h1><decorator:title default="Welcome!" /></h1>
<p><decorator:body /></p>
<p><small>
(<a
href="?printable=true">printable version</a>
</small></p>
</body>
</html>
查看這個(gè)裝飾器(decorator),我們能看到一些有趣的東西。首先,在第一行申明了一個(gè)SiteMesh標(biāo)簽庫。這個(gè)標(biāo)簽庫包含了與原始頁面一起工作時(shí)所需的所有東西。你能看到我們使用了兩個(gè)SiteMesh的裝飾標(biāo)簽(declared
tags), <decorator:title>
和 <decorator:body>
。不要驚訝于標(biāo)簽<decorator:title>在原始頁面中顯示<title>標(biāo)簽中的內(nèi)容, <decorator:body>
中的內(nèi)容也是如此。我們在這個(gè)頁面的HEAD和BODY元素都使用了同一個(gè)title標(biāo)簽。(We're making a few fairly radical
changes to the page, including repeating the title both in the HEAD
element as well as the BODY
. )同時(shí),我們還增加了一個(gè)到可打印版本頁面的鏈接。
作為對照,圖三顯示了原始處理頁面,圖四顯示了被修飾過的處理頁面。留意被裝飾頁面在瀏覽器窗口顯示的標(biāo)題文字和HTML內(nèi)容。同時(shí)也可以看到增加了一個(gè)可打印頁面的鏈接——這個(gè)我們回頭再說。
圖三:原始未修飾頁面
圖四:被修飾頁面
很明顯,對比起使用include(例如<jsp:include page="foo.jsp" flush="true" />)來說,以這樣的方式使用頁頭、頁尾系統(tǒng)結(jié)構(gòu)要清晰得多。這種方式更易移植、更易理解,同時(shí)也鼓勵(lì)了JSP頁面不再使用導(dǎo)航或其他類似的表現(xiàn)層代碼。我發(fā)現(xiàn)在JSP頁面中使用裝飾器和CSS的組合比標(biāo)準(zhǔn)HTML的標(biāo)簽更容易去除格式信息。
安裝SiteMesh
注意下面的屏幕截圖是基于Windows XP Professional, Tomcat 5.0.19,和Java 2 SDK 1.4.2_03的環(huán)境之上的。在這里我假定你的Tomcat已經(jīng)安裝完畢并且可以正常工作了。你或許會(huì)有一些混淆,但我們已經(jīng)成功地在Tomcat 4.1 和 WebLogic 測試過,同時(shí) SiteMesh 也支持大部分的web應(yīng)用服務(wù)器。
本文描述的SiteMesh 2.0.1可以在 下載到。 在java.net 上SiteMesh's 的項(xiàng)目庫中有四個(gè)文件可以下載。sitemesh-2.0.1.jar 是其核心 JAR 文件, sitemesh-2.0.1-sources.zip 的作用正如同其名字所述, sitemesh-example.war 則提供了一個(gè)復(fù)雜的例子用來顯示一些SiteMesh的高級特性。
為了使描述更加簡單,我們從sitemesh-blank.war 文件開始。將該WAR文件放入Tomcat 的webapps 目錄,WAR包將自動(dòng)解壓顯示內(nèi)容(SoSo注:這里的前提是你的tomcat已經(jīng)開始工作),如圖五所示。
圖五: SiteMesh_blank.WAR解開后的內(nèi)容
我們花點(diǎn)時(shí)間描述一下這些文件的作用。
web.xml
首先,WEB-INF/web.xml 文件顯示如列表3,這些語句用來安裝SiteMesh 過濾器和標(biāo)簽庫。如果你決定在一個(gè)已有的Web應(yīng)用中使用SiteMesh,你必須把這些語句添加到你的WEB-INF/web.xml 文件中。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Start of SiteMesh stuff -->
<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>*.jsp</url-pattern>
</filter-mapping>
<taglib>
<taglib-uri>sitemesh-page</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-decorator</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
</taglib>
<!-- End of SiteMesh stuff -->
</web-app>
注意:這里需要注意一下url-pattern
的寫法-- 如果使用的是Tomcat
5(而不是 Tomcat 4 ),需要將默認(rèn)的*修改如*.jsp的形式。最新的servlet規(guī)范不再支持*樣式。
decorators.xml
WEB-INF/decorators.xml 文件用來將一個(gè)裝飾器名字同一個(gè)專門的JSP裝飾文件綁定。作為一個(gè)例子,這里將JSP裝飾文件minimal.jsp同一個(gè)稱為handheld的裝飾器綁定起來。
<decorators defaultdir="/decorators">
<decorator name="main" page="main.jsp">
<pattern>*</pattern>
</decorator>
<decorator name="panel" page="panel.jsp"/>
<decorator name="printable" page="printable.jsp"/>
</decorators>
正如我們在代碼列表里看到的一樣,我們定義了三個(gè)裝飾器,他們分別綁定了三個(gè)類似的JSP頁面。我們可以看到一個(gè)默認(rèn)裝飾器(main.jsp),它將被默認(rèn)運(yùn)用于所有文件。
缺省的,SiteMesh使用下面的邏輯來選擇使用哪一個(gè)裝飾器:
這個(gè)邏輯在sitemesh-2.0.1.jar 包的 \com\opensymphony\module\sitemesh\factor\sitemesh-default.xml 文件里被描述。你可以針對諸如:客戶端操作系統(tǒng),web瀏覽器,用戶代理等在WEB-INF\sitemesh.xml文件里,通過一個(gè)變量覆蓋這個(gè)行為。(You can override this behavior with a wide variety of built-in mappers for things like language, client operating system, web browser/user agent, etc. by creating a WEB-INF\sitemesh.xml file. )可以在sitemesh-example.war 找到例子。 |
- 頁面是否使用meta裝飾器標(biāo)簽(meta decorator tag)特別指定了一個(gè)裝飾器?
- 頁面是否是一個(gè)框架集(是的話則不應(yīng)用裝飾器)?
- 頁面是否使用了
printable=true
參數(shù)(是的話則使用打印裝飾器) - 頁面時(shí)候使用裝飾器文件名特別指定了一個(gè)裝飾器?
- 頁面是否匹配 decorators.xml 文件里描述的樣式?
通常第一條規(guī)則僅用來確定該裝飾器是否被使用(Conceptually, the first rule that evaluates to true
determines the decorator that is used. )在上面的例子中,當(dāng)出現(xiàn)printable=true
參數(shù)的時(shí)候,裝飾器printable.jsp
(規(guī)則 #3)替代了 main.jsp
(規(guī)則 #5)。在SiteMesh中,這些規(guī)則被描述為
mappers。
decorators/*.jsp
這三個(gè)decorators目錄下的文件是decorators.xml文件中描述的不同裝飾器JSP文件。上面是一個(gè)簡單的裝飾器例子,在后面我們將討論更復(fù)雜的示例。
sitemesh-2.0.1.jar
這是SiteMesh最主要的二進(jìn)制文件,通常被安裝在 WEB-INF/lib 目錄下。可以在www.opensymphony.com/sitemesh/api 找到這個(gè)庫的javadoc。
*.tld
SiteMesh使用兩個(gè)標(biāo)簽庫,但大多數(shù)人都只需要sitemesh-decorator.tld。你可以在 www.opensymphony.com/sitemesh/tags.html 找到相應(yīng)的文檔。我們已經(jīng)講述了最主要的標(biāo)簽:head,title和body。在下一章我們來討論剩下的標(biāo)簽:getProperty。
SiteMesh高級特性
SiteMesh的一個(gè)重要特性是使用原始HTML的meta標(biāo)簽(例如<meta name="foo" content="bar">)從基礎(chǔ)頁面?zhèn)鬟f信息到裝飾器。作為一個(gè)例子,下面我們使用一個(gè)meta標(biāo)簽來定義HTML頁面的作者。
<html>
<meta name="author" content="test@example.com">
<head>
<title>Simple Document</title>
</head>
<body>
Hello World! <br />
<%= 1+1 %>
</body>
</html>
我們定義一個(gè)“smart”裝飾器來研究meta標(biāo)簽,如果出現(xiàn)這個(gè)標(biāo)簽,則可以得到一個(gè)相應(yīng)的HTML:
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
<decorator:usePage id="myPage" />
<html>
<head>
<title>My Site -
<decorator:title default="Welcome!" />
</title>
<decorator:head />
</head>
<body>
<h1><decorator:title default="Welcome!" /></h1>
<h3>
<a href="mailto:<decorator:getProperty property="meta.author"
default="staff@example.com" />">
<decorator:getProperty property="meta.author"
default="staff@example.com" />
</a></h3><hr />
<decorator:body />
<p><small>
(<a href="?printable=true">printable version</a>
</small>
</p>
</body>
</html>
可以看到我們使用了getProperty標(biāo)簽的一個(gè)默認(rèn)屬性——如果沒有指定author,我們就設(shè)定其為staff。如果你決定使用這個(gè)模型儲(chǔ)存頁面的meta數(shù)據(jù),你或許需要和你的開發(fā)伙伴一起來確定將使用什么標(biāo)簽以及如何使用他們。簡單的,你或許想要使用meta標(biāo)簽來描述諸如頁面作者及時(shí)間戳之類的東西。更復(fù)雜一些,你或許會(huì)想像XML文件一樣標(biāo)準(zhǔn)化的管理你的站點(diǎn)導(dǎo)航,同時(shí)使用meta標(biāo)簽來通過頁面節(jié)點(diǎn)轉(zhuǎn)到裝飾器。(At
the complex end, you may do things like standardize on an XML file to manage
your site navigation and use a meta
tag to
pass the page's node to the decorator. )
圖六顯示了應(yīng)用上面的裝飾器JSP頁面之后生成的結(jié)果。
圖六:meta標(biāo)簽顯示
這些頁面屬性非常強(qiáng)大,并且擁有著很多不同的特性,并不僅止于meta標(biāo)簽( 常用頁面特性列表)。使用SiteMesh一段時(shí)間之后,你就會(huì)開始思考HTML和JSP作為一種簡單標(biāo)記語言的機(jī)制——接近最原始的HTML——無需操作就可以完整的切換到XML/XSL 或其他模版引擎。
小結(jié)
綜上所述,SiteMesh 提供了一個(gè)強(qiáng)大、易用、易結(jié)合的機(jī)制來使用頁面模版。可以想象,它將會(huì)有很廣泛的用戶群。例如,你可以定義一個(gè)裝飾器針對不同的瀏覽器輸出額外的頁面調(diào)試信息(和特定web瀏覽器結(jié)合之后將產(chǎn)生一個(gè)特別的功能,你可以強(qiáng)制指定使用某一種用戶代理)。你也可以定義一個(gè)裝飾器產(chǎn)生stripped-down XML輸出,用來進(jìn)行簡單的自動(dòng)化測試。你甚至可以使用裝飾器從其他頁面提取內(nèi)容,例如輸出到一些簡單的門戶容器。
從sitemesh-blank.war入手比較容易,但我建議學(xué)習(xí) sitemesh-example.war 以獲取更多的特性和思想。
不論你如何使用SiteMesh,我都發(fā)現(xiàn)它將大量的代碼從表現(xiàn)層中移到我的裝飾器中,而無需學(xué)習(xí)一種新的編程語言或是模版系統(tǒng)。
對了,作為最后的補(bǔ)充,如果你仍然對組合建立web頁面感興趣,可以查看home.worldonline.dk/viksoe/asmil.htm 。
祝好運(yùn)并享受編程的樂趣!