Tiles 框架增強了基于組件的 Web UI 開發的設計,它和 Struts 框架的組合工作得很好。您可以很容易的協同 WebShpere Studio 使用 Tiles 和 Struts 框架以顯著降低您的 Web 開發工程的開發時間和維護代價。
? Copyright International Business Machines Corporation 2003. All rights reserved.
引言
Struts 是有名的模型-視圖-控制器(Model-View-Controller,MVC)框架方面的開放源碼體現之一,它提供了一種便利的方式,可以用于將模塊化應用程序清楚地分解成邏輯、表示和數據。Java 服務器頁面(Java?Server Pages,JSP)在 MVC 框架中的作用通常是作為視圖(View),它根據業務邏輯和數據生成動態的用戶界面(UI)。
在另一方面,Tiles 框架增強了基于組件的設計和 Web UI 設計中的模板概念。它可以幫助開發人員解除 Web UI 組件之間的耦合并重用它們。另外,Tiles 模板及其繼承特征使您能夠以最小量的工作為 Web 應用程序設計出一致的外觀。
IBM? WebSphere? Studio Application Developer Version 5(以下簡稱為 Application Developer)有內置的對 Struts 1.02 和 1.1(Beta 測試版 2)的工具和運行時支持。Tiles 可以獨立于 Struts 使用,也可以與 Struts framework 集成以支持高級特征。
重用 Web UI 組件的需要
本文假定您具有 Struts 和 Application Developer 中的 Struts 工具的基本知識。如果您對本主題的一些基本信息感興趣,請參閱 用WebSphere Studio V5 編寫一個簡單的 Struts 應用。
為了更好地理解可以如何重用 Web UI 組件,讓我們先來看一下圖 1 和 2 中的兩個 Web 頁面(JSP):
圖 1. IBM 解決方案頁面
圖 2. IBM 新聞頁面
您可以看到,這兩個頁面在頁頭、左側的導航條和頁腳中有很多組件是共有的。您可以不共享任何組件而為每一個頁面創建單獨的 JSP 來負責它的布局并且使用重復的頁頭、左側導航條和頁腳。當然,這種解決方案的效率是非常低的,因為對相同的 UI 組件(比如左側導航條)的更改要求您改動每個相關的頁面。
在上面的示例中,有大量的 HTML 和 JSP 代碼是重復的,而 UI 組件是緊耦合的。眾所周知,在軟件工程中緊耦合的組件將導致高額的維護成本。一個更好的解決方案是解除 UI 組件(頁頭、導航、頁腳和主體)之間的耦合并在不同的頁面中重用它們。
<jsp:include> 標簽為重用 Web UI 組件提供了一種解決方案。通過使用 <jsp:include> 標簽,Solutions 頁面和 News 頁面可以分解成由四個 JSP 頁面,如圖 3 和 4 所示:
圖 3. Solutions.jsp
圖 4. News.jsp
Solutions 頁面的 JSP 代碼顯示在示例 1 中,News 頁面的 JSP 代碼顯示在示例 2 中:
示例 1. Solutions.jsp 使用了 JSP 包含標簽(SimpleJSPWeb)
<HTML>
<HEAD>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><jsp:include page="/Header.jsp" /></TD>
</TR>
<TR>
<TD width="20%" valign="top"><jsp:include page="/Navigation.jsp" /></TD>
<TD width="80%" valign="top">
<jsp:include
page="/Fragment-Solutions.jsp" /></TD>
<TR>
<TD colspan="2"><jsp:include page="/Footer.jsp" /></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
示例 2. News.jsp 使用了 JSP 包含標簽(SimpleJSPWeb)
<HTML>
<HEAD>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><jsp:include page="/Header.jsp" /></TD>
</TR>
<TR>
<TD width="20%" valign="top"><jsp:include page="/Navigation.jsp" /></TD>
<TD width="80%" valign="top">
<jsp:include
page="/Fragment-News.jsp" /></TD>
<TR>
<TD colspan="2"><jsp:include page="/Footer.jsp" /></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
Solutions.jsp and News.jsp 的樣本代碼在 StrutsTiles.zip 下載文件 的 SimpleJSPWeb 項目中。下載并解壓 StrutsTiles.zip 后將 EAR 文件導入到一個工作區中:
在 Workbench 菜單中選擇 File => Import => EAR file。
單擊 Browse選擇 EAR 文件。
輸入 StrutsTiles 作為項目名稱。
要運行任何一個樣本,可以遵循下列操作步驟:
右鍵單擊 News.jsp和 Solutions.jsp,然后選擇 Run on Server。
Tiles 插入標簽提供和 JSP 包含標簽相同的功能。下面的 JSP 代碼反映包含使用 Tiles 插入標簽的解決方案:
示例 3. Solutions.jsp 帶有 Tiles 插入標簽(SimpleTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2">
<tiles:insert page="/Header.jsp" flush="true"/>
</TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert page="/Navigation.jsp" flush="true"/>
</TD>
<TD width="80%" valign="top">
<tiles:insert page="/Fragment-Solutions.jsp" flush="true" />
</TD>
</TR>
<TR>
<TD colspan="2">
<tiles:insert page="/Footer.jsp" flush="true"/>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
示例 4. News.jsp 帶有 Tiles 插入標簽(SimpleTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2">
<tiles:insert page="/Header.jsp" flush="true"/>
</TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert page="/Navigation.jsp" flush="true"/>
</TD>
<TD width="80%" valign="top">
<tiles:insert page="/Fragment-News.jsp" flush="true" />
</TD>
</TR>
<TR>
<TD colspan="2">
<tiles:insert page="/Footer.jsp" flush="true"/>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
JSP 包含標簽和 Tiles 插入標簽都解除了 Web UI 組件的耦合。改變一個單獨的 UI 組件只需要改變負責該頁面的組件,例如 Header.jsp ,而其他頁面并不需要改變。示例 3 和 4 的代碼位于 SimpleTilesWeb 中。
然而,在以上示例中,如果 Web 應用的 UI 布局需要從圖 5 改變到圖 6,在后者中主體組件可能是 fragment-Solutions.jsp 或 fragment-News.jsp ,那么有多少頁面需要修改呢?如果有 N 個頁面有相同的布局,您將需要修改所有的 N 個頁面。因此,如果僅僅使用一個 JSP 包含標簽或 Tiles 插入標簽,Web 應用 UI 的布局仍然是各 JSP 彼此緊耦合的。我們需要找到一個方法來將 JSP 進行更深層的解耦合。
圖 5
圖 6
使用 Tiles 創建模板
我們面臨的新的挑戰是找到一個便捷的方法將 Web UI 從一個布局轉換到另一個布局。Tiles 模板的特征滿足該要求。
什么是 Tiles 模板?
Tiles 模板是一個一般不包含任何實際內容的布局。它包含一些占位符屬性使得頁面 URI 和字符串可以在將來被插入。內容頁面如 News.jsp 和 Solutions.jsp 可以引用該模板并通過這些占位符屬性插入 URI。
為創建一個模板頁面,您可以使用 Tiles 插入標簽。不像示例 3 中的插入標簽,在 Tiles 模板中使用的插入標簽僅有一個名為 attribute 的屬性,它將變成 JSP 頁面 URI 插入的占位符。創建頁頭占位符的模板代碼為 <tiles:insert attribute="header" /> 。
該模板定義了具體的頁面可以引用的 Web UI 組件的共同布局。以下 JSP 代碼就是使用 Tiles 的一個樣本模板:
示例 5. Layout.jsp 是 Tiles 模板 (TemplatingTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><tiles:insert attribute="header"/></TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert attribute="navigation"/></TD>
<TD width="80%" valign="top">
<tiles:insert attribute="body"/></TD>
</TR>
<TR>
<TD colspan="2"><tiles:insert attribute="footer"/></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
在定義完一個模板之后,它本身是不可以使用的。實際的 JSP 頁面必須引用該模板并且為其屬性提供頁面 URI。 <tiles:insert page="/Layout.jsp"flush="true"> 行可用于引用該模板。
具體的 JSP 頁面將布局組合委托給模板 Layout.jsp 。它們需要為使用 Tiles put 標簽的 attribute 指定頁面實現名稱。代碼 <tiles:put name="header" value="/Header.jsp"/> 將頁面 /Header.jsp 插入名為 header 的屬性。下面是使用 Tiles 模板特征的 Solutions.jsp 和 News.jsp 的 JSP 代碼:
示例 6. 具有 Tiles 模板特征(TemplatingTilesWeb)的 Solutions.jsp
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert page="/Layout.jsp" flush="true">
<tiles:put name="header" value="/Header.jsp"/>
<tiles:put name="navigation" value="/Navigation.jsp"/>
<tiles:put name="body"
value="/Fragment-Solutions.jsp"/>
<tiles:put name="footer" value="/Footer.jsp"/></tiles:insert>
示例 7. 具有 Tiles 模板特征(TemplatingTilesWeb)的 News.jsp
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert page="/Layout.jsp" flush="true">
<tiles:put name="header" value="/Header.jsp"/>
<tiles:put name="navigation" value="/Navigation.jsp"/>
<tiles:put name="body"
value="/Fragment-News.jsp"/>
<tiles:put name="footer" value="/Footer.jsp"/></tiles:insert>
示例 5、6 和 7 的代碼在 TemplatingTilesWeb 中。
如果想將布局從圖 5 改變到圖 6,您所需要做的只是如示例 8 中所示修改模板 Layout.jsp ,而不需要改動具體頁面,比如 Solutions.jsp 和 News.jsp 。相比較未使用模板時需要修改 N 個頁面,使用了 Tiles 模板特征可以顯著地降低維護成本。
示例 8. 修改模板以創建新的布局
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><tiles:insert attribute="header"/></TD>
</TR>
<TR>
<TD width="80%" valign="top">
<tiles:insert attribute="body"/></TD>
<TD width="20%" valign="top">
<tiles:insert attribute="navigation"/></TD>
</TR>
<TR>
<TD colspan="2"><tiles:insert attribute="footer"/></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
? Copyright International Business Machines Corporation 2003. All rights reserved.
引言
Struts 是有名的模型-視圖-控制器(Model-View-Controller,MVC)框架方面的開放源碼體現之一,它提供了一種便利的方式,可以用于將模塊化應用程序清楚地分解成邏輯、表示和數據。Java 服務器頁面(Java?Server Pages,JSP)在 MVC 框架中的作用通常是作為視圖(View),它根據業務邏輯和數據生成動態的用戶界面(UI)。
在另一方面,Tiles 框架增強了基于組件的設計和 Web UI 設計中的模板概念。它可以幫助開發人員解除 Web UI 組件之間的耦合并重用它們。另外,Tiles 模板及其繼承特征使您能夠以最小量的工作為 Web 應用程序設計出一致的外觀。
IBM? WebSphere? Studio Application Developer Version 5(以下簡稱為 Application Developer)有內置的對 Struts 1.02 和 1.1(Beta 測試版 2)的工具和運行時支持。Tiles 可以獨立于 Struts 使用,也可以與 Struts framework 集成以支持高級特征。
重用 Web UI 組件的需要
本文假定您具有 Struts 和 Application Developer 中的 Struts 工具的基本知識。如果您對本主題的一些基本信息感興趣,請參閱 用WebSphere Studio V5 編寫一個簡單的 Struts 應用。
為了更好地理解可以如何重用 Web UI 組件,讓我們先來看一下圖 1 和 2 中的兩個 Web 頁面(JSP):
圖 1. IBM 解決方案頁面
圖 2. IBM 新聞頁面
您可以看到,這兩個頁面在頁頭、左側的導航條和頁腳中有很多組件是共有的。您可以不共享任何組件而為每一個頁面創建單獨的 JSP 來負責它的布局并且使用重復的頁頭、左側導航條和頁腳。當然,這種解決方案的效率是非常低的,因為對相同的 UI 組件(比如左側導航條)的更改要求您改動每個相關的頁面。
在上面的示例中,有大量的 HTML 和 JSP 代碼是重復的,而 UI 組件是緊耦合的。眾所周知,在軟件工程中緊耦合的組件將導致高額的維護成本。一個更好的解決方案是解除 UI 組件(頁頭、導航、頁腳和主體)之間的耦合并在不同的頁面中重用它們。
<jsp:include> 標簽為重用 Web UI 組件提供了一種解決方案。通過使用 <jsp:include> 標簽,Solutions 頁面和 News 頁面可以分解成由四個 JSP 頁面,如圖 3 和 4 所示:
圖 3. Solutions.jsp
圖 4. News.jsp
Solutions 頁面的 JSP 代碼顯示在示例 1 中,News 頁面的 JSP 代碼顯示在示例 2 中:
示例 1. Solutions.jsp 使用了 JSP 包含標簽(SimpleJSPWeb)
<HTML>
<HEAD>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><jsp:include page="/Header.jsp" /></TD>
</TR>
<TR>
<TD width="20%" valign="top"><jsp:include page="/Navigation.jsp" /></TD>
<TD width="80%" valign="top">
<jsp:include
page="/Fragment-Solutions.jsp" /></TD>
<TR>
<TD colspan="2"><jsp:include page="/Footer.jsp" /></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
示例 2. News.jsp 使用了 JSP 包含標簽(SimpleJSPWeb)
<HTML>
<HEAD>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><jsp:include page="/Header.jsp" /></TD>
</TR>
<TR>
<TD width="20%" valign="top"><jsp:include page="/Navigation.jsp" /></TD>
<TD width="80%" valign="top">
<jsp:include
page="/Fragment-News.jsp" /></TD>
<TR>
<TD colspan="2"><jsp:include page="/Footer.jsp" /></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
Solutions.jsp and News.jsp 的樣本代碼在 StrutsTiles.zip 下載文件 的 SimpleJSPWeb 項目中。下載并解壓 StrutsTiles.zip 后將 EAR 文件導入到一個工作區中:
在 Workbench 菜單中選擇 File => Import => EAR file。
單擊 Browse選擇 EAR 文件。
輸入 StrutsTiles 作為項目名稱。
要運行任何一個樣本,可以遵循下列操作步驟:
右鍵單擊 News.jsp和 Solutions.jsp,然后選擇 Run on Server。
Tiles 插入標簽提供和 JSP 包含標簽相同的功能。下面的 JSP 代碼反映包含使用 Tiles 插入標簽的解決方案:
示例 3. Solutions.jsp 帶有 Tiles 插入標簽(SimpleTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2">
<tiles:insert page="/Header.jsp" flush="true"/>
</TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert page="/Navigation.jsp" flush="true"/>
</TD>
<TD width="80%" valign="top">
<tiles:insert page="/Fragment-Solutions.jsp" flush="true" />
</TD>
</TR>
<TR>
<TD colspan="2">
<tiles:insert page="/Footer.jsp" flush="true"/>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
示例 4. News.jsp 帶有 Tiles 插入標簽(SimpleTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2">
<tiles:insert page="/Header.jsp" flush="true"/>
</TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert page="/Navigation.jsp" flush="true"/>
</TD>
<TD width="80%" valign="top">
<tiles:insert page="/Fragment-News.jsp" flush="true" />
</TD>
</TR>
<TR>
<TD colspan="2">
<tiles:insert page="/Footer.jsp" flush="true"/>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
JSP 包含標簽和 Tiles 插入標簽都解除了 Web UI 組件的耦合。改變一個單獨的 UI 組件只需要改變負責該頁面的組件,例如 Header.jsp ,而其他頁面并不需要改變。示例 3 和 4 的代碼位于 SimpleTilesWeb 中。
然而,在以上示例中,如果 Web 應用的 UI 布局需要從圖 5 改變到圖 6,在后者中主體組件可能是 fragment-Solutions.jsp 或 fragment-News.jsp ,那么有多少頁面需要修改呢?如果有 N 個頁面有相同的布局,您將需要修改所有的 N 個頁面。因此,如果僅僅使用一個 JSP 包含標簽或 Tiles 插入標簽,Web 應用 UI 的布局仍然是各 JSP 彼此緊耦合的。我們需要找到一個方法來將 JSP 進行更深層的解耦合。
圖 5
圖 6
使用 Tiles 創建模板
我們面臨的新的挑戰是找到一個便捷的方法將 Web UI 從一個布局轉換到另一個布局。Tiles 模板的特征滿足該要求。
什么是 Tiles 模板?
Tiles 模板是一個一般不包含任何實際內容的布局。它包含一些占位符屬性使得頁面 URI 和字符串可以在將來被插入。內容頁面如 News.jsp 和 Solutions.jsp 可以引用該模板并通過這些占位符屬性插入 URI。
為創建一個模板頁面,您可以使用 Tiles 插入標簽。不像示例 3 中的插入標簽,在 Tiles 模板中使用的插入標簽僅有一個名為 attribute 的屬性,它將變成 JSP 頁面 URI 插入的占位符。創建頁頭占位符的模板代碼為 <tiles:insert attribute="header" /> 。
該模板定義了具體的頁面可以引用的 Web UI 組件的共同布局。以下 JSP 代碼就是使用 Tiles 的一個樣本模板:
示例 5. Layout.jsp 是 Tiles 模板 (TemplatingTilesWeb)
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><tiles:insert attribute="header"/></TD>
</TR>
<TR>
<TD width="20%" valign="top">
<tiles:insert attribute="navigation"/></TD>
<TD width="80%" valign="top">
<tiles:insert attribute="body"/></TD>
</TR>
<TR>
<TD colspan="2"><tiles:insert attribute="footer"/></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
在定義完一個模板之后,它本身是不可以使用的。實際的 JSP 頁面必須引用該模板并且為其屬性提供頁面 URI。 <tiles:insert page="/Layout.jsp"flush="true"> 行可用于引用該模板。
具體的 JSP 頁面將布局組合委托給模板 Layout.jsp 。它們需要為使用 Tiles put 標簽的 attribute 指定頁面實現名稱。代碼 <tiles:put name="header" value="/Header.jsp"/> 將頁面 /Header.jsp 插入名為 header 的屬性。下面是使用 Tiles 模板特征的 Solutions.jsp 和 News.jsp 的 JSP 代碼:
示例 6. 具有 Tiles 模板特征(TemplatingTilesWeb)的 Solutions.jsp
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert page="/Layout.jsp" flush="true">
<tiles:put name="header" value="/Header.jsp"/>
<tiles:put name="navigation" value="/Navigation.jsp"/>
<tiles:put name="body"
value="/Fragment-Solutions.jsp"/>
<tiles:put name="footer" value="/Footer.jsp"/></tiles:insert>
示例 7. 具有 Tiles 模板特征(TemplatingTilesWeb)的 News.jsp
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert page="/Layout.jsp" flush="true">
<tiles:put name="header" value="/Header.jsp"/>
<tiles:put name="navigation" value="/Navigation.jsp"/>
<tiles:put name="body"
value="/Fragment-News.jsp"/>
<tiles:put name="footer" value="/Footer.jsp"/></tiles:insert>
示例 5、6 和 7 的代碼在 TemplatingTilesWeb 中。
如果想將布局從圖 5 改變到圖 6,您所需要做的只是如示例 8 中所示修改模板 Layout.jsp ,而不需要改動具體頁面,比如 Solutions.jsp 和 News.jsp 。相比較未使用模板時需要修改 N 個頁面,使用了 Tiles 模板特征可以顯著地降低維護成本。
示例 8. 修改模板以創建新的布局
<HTML>
<HEAD>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<TITLE>IBM Solutions</TITLE>
</HEAD>
<BODY>
<TABLE border="0">
<TBODY>
<TR>
<TD colspan="2"><tiles:insert attribute="header"/></TD>
</TR>
<TR>
<TD width="80%" valign="top">
<tiles:insert attribute="body"/></TD>
<TD width="20%" valign="top">
<tiles:insert attribute="navigation"/></TD>
</TR>
<TR>
<TD colspan="2"><tiles:insert attribute="footer"/></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
