重用標(biāo)題,簡化用戶界面 | |
作者:James Ho… 文章來源:OTN 點擊數(shù):85 更新時間:2006-7-16 | |
【字體:小 大】 | |
| |
如果您有任何疑問,請到開發(fā)論壇上提問。 | |
| |
利用Tiles簡化和增強(qiáng)Struts的 JSP開發(fā) JSP(JavaServer Pages)技術(shù)通過includes支持應(yīng)用程序?qū)ο蟮闹赜茫篿ncludes允許其他文件(包括其他JSP文件)在編譯時或者在應(yīng)用程序運(yùn)行時動態(tài)地被嵌入JSP文件。該特性非常有用,它可以將頁面的共用組件,諸如報頭、頁腳以及菜單提取出來,作為可重用組件被多個文件所用。 Includes功能很強(qiáng)大,并且可以節(jié)約時間,但是他們卻會帶來組件大量重復(fù)的潛在問題。 每個嵌入共用組件的JSP文件都復(fù)制include定義。如果被包含的文件的名稱改變了,那么每個使用Include引用這些文件的文件都需要被更新。 Tiles框架就是為了解決該局限性和增強(qiáng)Struts框架的功能而創(chuàng)建的。Tiles利用includes通過允許用戶定義模板(布局),然后指定模板內(nèi)容的裝入方式,而擴(kuò)展了重用的概念。 借助JSP的include范例,每個JSP通過include指定其模板和明確地給出內(nèi)容的裝入方式。大多數(shù)JSP的模板是相同的:在相同的地方裝入相同的文件,只有加入獨(dú)特內(nèi)容(主體內(nèi)容)部分是不同的。借助Tiles,可以使用一個外部配置文件定義一個主模板JSP,后者指定每個用于裝填模板的include,然后定義哪個內(nèi)容需要加入該模板。比如,設(shè)想一下你有一個典型的網(wǎng)站模板:頁面頂端有一個報頭(標(biāo)題),左側(cè)有一個菜單,中間部分為主體內(nèi)容,底部是頁腳。如果你僅僅使用JSP的includes來實現(xiàn)這種模板,每個具有這種模板的JSP不得不明確包含報頭、菜單、頁腳各部分以及頁面的主體內(nèi)容。該頁面中唯一獨(dú)特的部分就是主體內(nèi)容。然而,如果你使用Tiles來實現(xiàn)該模板,那么,你只需要創(chuàng)建一個包含報頭、菜單和頁腳的JSP文件,基于能夠傳遞給模板的用來指定哪個JSP文件包含主體內(nèi)容的屬性,就可以動態(tài)地包含主體內(nèi)容。根據(jù)你的愿望,該Tiles模板能夠被一次再一次地重復(fù)用于許多頁面,你的內(nèi)容JSPs必須包含的東西就是位于頁面中部的獨(dú)特的主體內(nèi)容。 將Tiles添加到你的應(yīng)用程序中 現(xiàn)在你已經(jīng)知道了使用Tiles框架的好處,下面是將Tiles添加到你的Struts應(yīng)用程序中所必要步驟:
下面詳細(xì)講述該過程的每個步驟。 將Tiles 標(biāo)記庫描述符文件添加到應(yīng)用程序。更新你的Struts應(yīng)用程序,以便使用Tiles的第一步是將Tiles標(biāo)記庫描述符文件添加到該應(yīng)用程序中。該步驟是必須的,只有這樣JSP才能使用Tiles標(biāo)記庫。Tiles標(biāo)記庫允許你在JSPs中使用Tiles模板。要將Tiles標(biāo)記庫描述符文件添加到該應(yīng)用程序中,需要從Struts發(fā)布庫目錄(例如,c:\java\jakarta-struts-1.1\lib)中將 struts-tiles.tld 文件拷貝到你的應(yīng)用程序的/WEB-INF/tlds目錄中。下一步,在你的應(yīng)用程序的Web部署描述符文件(web.xml)中添加一個標(biāo)記庫描述符(TLD)項,并按如下所示注冊Tiles的標(biāo)記庫描述符:
<taglib> <taglib-uri> /WEB-INF/tlds/struts-tiles.tld </taglib-uri> <taglib-location> /WEB-INF/tlds/struts-tiles.tld </taglib-location> </taglib>
現(xiàn)在可以通過使用如下所示的代碼,從你的JSPs中引用TLD:
<%@ taglib uri="/WEB-INF/tlds/struts-tiles.tld" prefix="tiles" %>
創(chuàng)建模板JSPs。既然你已經(jīng)注冊了Tiles的標(biāo)記庫描述符,那么現(xiàn)在就可以創(chuàng)建模板JSPs。代碼清單 1所示的模板描述了Tile的基本概念。該模板是在你應(yīng)用程序已有的頁面結(jié)構(gòu)的基礎(chǔ)上創(chuàng)建的。 請注意,代碼清單 1中模板頁面的主體內(nèi)容采用黑體字。對于每個不同的頁面,該部分內(nèi)容是不相同的。然而,頁面的其他部分對這幾個頁面來說是相同的,這樣就可以將它們提取出來構(gòu)成一個通用的模板。 3個JSP文件--mainLayout.jsp、 header.jsp和 footer.jsp--構(gòu)成了該模板。mainLayout.jsp 文件如下所示:
<%@ taglib uri="/WEB-INF/tlds/struts-tiles.tld" prefix="tiles" %> <html> <head> <title> <tiles:getAsString name="title"/> </title> </head> <body> <tiles:insert attribute="header"/> <tiles:insert attribute="body"/> <tiles:insert attribute="footer"/> </body> </html>
該JSP文件定義了布局的模板,用于嵌入其他模板JSP以及主體內(nèi)容。主體內(nèi)容和其他模板JSP通過<tiles:insert>標(biāo)記來嵌入。這些標(biāo)記指定在Tiles配置文件中定義的屬性的名稱,這些屬性的值是在運(yùn)行時應(yīng)被插入到JSP中的JSPs的名字。請注意<tiles:getAsString>標(biāo)記的用法。該標(biāo)記的作用與<tiles:insert> 標(biāo)記類似,但是與后者使用被包含的頁面的名稱作為指定的屬性值不同,它使用文本串來作為指定的屬性值。該方法適用于將小塊內(nèi)容動態(tài)地插入模板,但不保證自有包含文件也被插入。 下面是報頭和頁腳模板JSPs:
header.jsp <font size="+1"> ABC, Inc. Human Resources Portal </font><br> <hr width="100%" noshade="true"> footer.jsp <hr width="100%" noshade="true"> Copyright © ABC, Inc.
這種報頭和頁腳JSPs都非常的簡單,不包含太多的HTML。這些JSPs的內(nèi)容可以直接放入mainLayout.jsp文件中,內(nèi)容頁面仍然只需包含頁面的主體內(nèi)容。 然而,將頁面拆分成多個小塊可提高模板的使用靈活性。如果你需要一些頁面必須使用定制的報頭和頁腳而其他頁面使用標(biāo)準(zhǔn)報頭和頁腳,則可以將報頭和頁腳分離成離散的組件,以便使你能做到這一點。你只需在模板級別上定義報頭和頁腳屬性的值,對于需要定制的報頭或頁腳(或二者),可在頁面這一級上用新的值取代相應(yīng)的值。 更新現(xiàn)有的JSPs以使用模板。在創(chuàng)建了模板JSPs之后,更新應(yīng)用程序的原始JSPs,以便只包含其頁面的主體內(nèi)容。要達(dá)成此目的,從原始頁面中移除共用的模板部分。代碼清單 2顯示了更新后的只包含主體內(nèi)容的示例頁面。 代碼清單 2中的已更新的頁面不再包含內(nèi)容的報頭和頁腳部分。在運(yùn)行時,模板JSPs用共用布局內(nèi)容填充已更新的頁面來創(chuàng)建完整的頁面。 創(chuàng)建文件tiles-defs.xml。有兩種聲明Tiles模板的方法:
下面所述的例子使用配置文件方式,因為這種方式更加靈活,并且更加容易維護(hù)。代碼清單 3顯示了聲明模板的tiles-defs.xml文件。該文件應(yīng)該位于你的應(yīng)用程序的/WEB-INF/ 文件夾中。 在該tiles-defs.xml 文件中有兩個Tiles的定義。該文件中的第一個定義聲明了名為main.layout的模板。通常,模板定義指定用于頁面的模板,也會指定屬性列表--這些屬性的值將會被用來完成模板的填充。 頁定義擴(kuò)展模板定義,并且為在擴(kuò)展模板中定義的屬性提供相應(yīng)的值。 請注意,代碼清單 3中的第一個定義--main.layout--用put標(biāo)記定義了4個屬性。這些屬性對于path屬性指定的模板JSP--mainLayout.jsp--可用。該模板JSP使用這些屬性來提供其內(nèi)容的位置。另外,與title屬性一樣,這些屬性能夠被用以支持文本串。mainLayout.jsp中使用了title屬性,因此它可以根據(jù)由頁面定義設(shè)置的值包含一個動態(tài)標(biāo)題(title),從而擴(kuò)展了模板的定義。 代碼清單 3的tiles-defs.xml 文件中的第二個定義聲明了一個被稱為search.page的頁面定義。該定義擴(kuò)展了main.layout定義,并且為在模板定義中無值的屬性提供值。該定義可以重設(shè)模板定義中的任何屬性,但在本例中只有標(biāo)題(title)和主體(body)屬性被重設(shè)。 更新struts-config.xml 文件中的傳遞定義,并且將Tiles插件添加到該文件中。在創(chuàng)建了Tiles配置文件之后,更新你的應(yīng)用程序的struts-config.xml 文件以指向Tiles定義,而不是直接指向每個已經(jīng)轉(zhuǎn)換成使用Tiles的頁面的JSPs,并把Tiles 插件添加到struts-config.xml文件中。 如果沒有Tiles,正向作用定義就直接指向JSPs。有了Tiles,他們就指向Tiles配置文件中的頁面定義。比如說,在這之前應(yīng)用程序的搜索行動(search action)直接指向search.jsp,如下所示:
<action path="/search" type="com.jamesholmes.minihr .SearchAction" name="searchForm" scope="request" validate="true" input="/search.jsp"/>
然而,有了Tiles之后,該動作就指向搜索頁面的Tiles定義,如下所示:
<action path="/search" type="com.jamesholmes.minihr .SearchAction" name="searchForm" scope="request" validate="true" input="search.page"/>
對于所有Struts配置文件中決定使用Tiles的傳遞和行動(forward and action)定義,如下例所示,用合適的Tiles頁面定義引用來代替相應(yīng)的JSP引用。
為了將Tiles插件添加到應(yīng)用程序,將以下代碼段添加到你的struts-config.xml文件中:
<!-- Tiles Configuration --> <plug-in className= "org.apache.struts.tiles.TilesPlugin"> <set-property property= "definitions-config" value="/WEB-INF/tiles-defs.xml"/> </plug-in>
該段代碼使得應(yīng)用程序在啟動時載入Tiles插件。請注意,Tiles配置文件由set-property標(biāo)記來指定。通過提供一個以逗號分隔的文件列表,可以用該標(biāo)記來指定多個配置文件。 代碼清單 4顯示了整個Struts配置文件。粗體顯示部分是被修改或者被添加的部分。重新打包,并且運(yùn)行更新后的該應(yīng)用程序。因為在該過程中,并沒有Java代碼被修改,所以不必要重新編譯應(yīng)用程序。然而,因為添加了一些文件和對一些做了修改,所以在應(yīng)用程序運(yùn)行之前,需要重新打包和重新部署。一旦使你的更新之后的應(yīng)用程序能夠運(yùn)行,那么所有的功能都會和以前一樣發(fā)揮其作用,但是現(xiàn)在你可以毫不費(fèi)力地添加新的頁面和對應(yīng)用程序做出全局性的改變。 結(jié)論 通過提供了一個功能強(qiáng)大的促進(jìn)頁面組件重用的模板創(chuàng)建系統(tǒng),Tiles框架極大地提高了核心Struts框架的價值。通過將Tiles框架用于你的JSP應(yīng)用程序,可以節(jié)約大量的時間,并且大大提高你的Struts應(yīng)用程序的開發(fā)效率。
James Holmes (james@jamesholmes.com)是一名獨(dú)立的Struts項目方面的Java咨詢專家和撰稿人。他是《Struts:完整的參考手冊》的作者,還是《Java的藝術(shù)》一書的合著者之一(兩本書都由McGraw-Hill/Osborne出版) |