記文件是 JavaServer Pages (JSP) 技術(shù)最重要的新增功能之一,它允許 Web 開(kāi)發(fā)人員利用 JSP 語(yǔ)法創(chuàng)建自定義的標(biāo)記庫(kù)。JSP 容器自動(dòng)將 JSP 標(biāo)記文件轉(zhuǎn)換為 Java 代碼,其過(guò)程與從 JSP 頁(yè)透明地生成 Java Servlet 的過(guò)程相同。可以說(shuō)標(biāo)記文件隱藏了創(chuàng)建自定義 JSP 標(biāo)記庫(kù)的復(fù)雜性。這種庫(kù)能夠在 Web 應(yīng)用程序中重用,它們甚至在用于特定應(yīng)用程序時(shí)也會(huì)提供顯著的效益,因?yàn)樽远x標(biāo)記提高了 Web 頁(yè)的可維護(hù)性。在閱讀本文后,您將了解如何創(chuàng)建和使用標(biāo)記文件以及如何將現(xiàn)有的頁(yè)片段變換為標(biāo)記文件。 JSP 2.0 定義了三個(gè)新的指示語(yǔ)句(<%@tag%>、<%@attribute%> 和 <%@variable%>)和兩個(gè)新的標(biāo)準(zhǔn)操作(<jsp:invoke> 和 <jsp:doBody>),它們只能在標(biāo)記文件中使用。我們將在整篇文章中使用它們,并且您將了解如何利用更加高級(jí)的標(biāo)記文件特性,如“動(dòng)態(tài)屬性”、“片段屬性”和“根據(jù)屬性命名的變量”。當(dāng)標(biāo)記文件與 JSP 標(biāo)準(zhǔn)標(biāo)記庫(kù) (JSTL) 同時(shí)使用時(shí),標(biāo)記文件可以是一種功能強(qiáng)大的工具,而 JSTL 引入了由 JSP 2.0 和許多 JSP 操作所采用的表達(dá)式語(yǔ)言,包括一系列 SQL 標(biāo)記。我們將使用 JSTL 和高級(jí)的 JSP 特性來(lái)創(chuàng)建標(biāo)記文件,用于更新和查詢(xún)數(shù)據(jù)庫(kù)。 標(biāo)記文件概述 JSP 1.x 允許 Web 開(kāi)發(fā)人員創(chuàng)建 Java 組件(稱(chēng)為標(biāo)記處理程序),這些組件是通過(guò)自定義標(biāo)記從 JSP 頁(yè)進(jìn)行調(diào)用的。標(biāo)記處理程序類(lèi)似于以前的 Java Servlet,因?yàn)槟褂煤芏?println() 調(diào)用來(lái)生成 HTML 內(nèi)容,然后必須編譯您的 Java 代碼。JSP 2.0 的標(biāo)記文件類(lèi)似于 JSP 頁(yè),因?yàn)槟褂?JSP 語(yǔ)法,然后 JSP 容器獲取您的 JSP 標(biāo)記文件,分析這些標(biāo)記文件,生成 Java 標(biāo)記處理程序,并自動(dòng)編譯它們。標(biāo)記文件是從 JSP 頁(yè)進(jìn)行調(diào)用的,JSP 頁(yè)使用與 <prefix:tagFileName> 模式相匹配的自定義標(biāo)記。 為了使標(biāo)記文件能夠被 JSP 容器所識(shí)別,標(biāo)記文件必須使用 .tag 文件擴(kuò)展名進(jìn)行命名,并且必須被放置在您的 Web 應(yīng)用程序的 /WEB-INF/tags 目錄中或者 /WEB-INF/tags 的子目錄中。如果您采用這種部署方法,則不必創(chuàng)建任何標(biāo)記庫(kù)描述器 (TLD),因?yàn)?JSP 庫(kù)是利用 Java 標(biāo)記處理程序所實(shí)施的。您也可以將標(biāo)記文件放置在 .jar 文件的 /META-INF/tags 目錄中,其部署更容易,但在這種情況下,您必須創(chuàng)建 TLD,并且必須在每次更改后重新對(duì)標(biāo)記文件進(jìn)行打包。 標(biāo)記文件和 JSP 頁(yè)使用幾乎相同的語(yǔ)法。您會(huì)注意到的第一個(gè)區(qū)別是新的 <%@tag%> 指示語(yǔ)句,它等同于 <%@page%>。這兩個(gè)指示語(yǔ)句具有相似的屬性,但前者用于標(biāo)記文件,而后者只能用于 JSP 頁(yè)中。標(biāo)記文件并不在一個(gè)單獨(dú)的 .tld 文件中聲明其屬性和變量,而是使用 <%@attribute%> 和 <%@variable%> 指示語(yǔ)句。當(dāng)從 JSP 頁(yè)調(diào)用標(biāo)記文件時(shí),自定義標(biāo)記可以具有主體(在 <prefix:tagFileName> 與 </prefix:tagFileName> 之間),該主體可以由標(biāo)記文件利用 <jsp:doBody> 操作來(lái)執(zhí)行。您在下一節(jié)中將會(huì)看到這是如何工作的。 使用標(biāo)記文件代替頁(yè)片段 為了擁有可維護(hù)的 Web 頁(yè),許多經(jīng)過(guò)良好設(shè)計(jì)的 JSP 1.x 應(yīng)用程序使用了頁(yè)片段,這些頁(yè)片段是利用 <jsp:include> 或 <%@include%> 而包含在較大頁(yè)面中的,而這不是在 Web 應(yīng)用程序中重用 JSP 片段的理想方法。與頁(yè)包含解決方案不同,標(biāo)記文件專(zhuān)用于創(chuàng)建可重用的頁(yè)片段庫(kù)。本節(jié)比較了過(guò)時(shí)的 JSP 1.x 方法的語(yǔ)法與 JSP 2.0 標(biāo)記文件的更好語(yǔ)法。 將被包含頁(yè)變換為標(biāo)記文件。讓我們假設(shè)您具有一個(gè)名為 container.jsp 的頁(yè)面,它利用 <jsp:include page="part.jsp"/> 包含了另一個(gè)名為 part.jsp 的頁(yè)面。執(zhí)行以下步驟,將 part.jsp 變換為標(biāo)記文件。 第 1 步:移動(dòng)被包含頁(yè)。 在您的應(yīng)用程序的 WEB-INF 目錄中,創(chuàng)建一個(gè)名為 tags 的子目錄,并將 part.jsp 頁(yè)移動(dòng)到 WEB-INF/tags 中。 第 2 步:重命名被包含頁(yè)。 由于標(biāo)準(zhǔn)的標(biāo)記文件擴(kuò)展名是 .tag,您必須將 part.jsp 重命名為 part.tag。 第 3 步:編輯標(biāo)記文件。 打開(kāi) part.tag 文件進(jìn)行編輯,將 <%@page%> 指示語(yǔ)句替換為類(lèi)似的 <%@tag%> 指示語(yǔ)句。如果遇到編譯錯(cuò)誤,則可能需要進(jìn)行其他一些小的修改。使用 jspContext 替代 pageContext。 第 4 步:聲明標(biāo)記庫(kù)。 在 container.jsp 的開(kāi)頭插入 <%@taglib prefix="tags" tagdir="/WEB-INF/tags"%>。 第 5 步:調(diào)用標(biāo)記文件。 在 container.jsp 中將 <jsp:include page="part.jsp"/> 替換為 <tags:part/>。 container.jsp(變換前) <p> Container Page </p> <jsp:include page="part.jsp"/> container.jsp(變換后) <%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> <p> Container Page </p> <tags:part/> part.jsp(變換前) <%@ page language="java" %> <p> Included Page </p> <%= pageContext.getClass().getName() %> part.tag(變換后) <%@ tag language="java" %> <p> Invoked tag </p> <%= jspContext.getClass().getName() %> 基于 <jsp:include> 和 <%@include%> 的示例。本示例的主頁(yè) (main.jsp) 使用 <%@include%> 指示語(yǔ)句包含了兩個(gè)頁(yè)片段(header.jspf 和 footer.jspf)。主頁(yè)還通過(guò)使用 <jsp:include> 來(lái)包含另一個(gè)頁(yè)面 (content.jsp)。main.jsp 頁(yè)利用 <jsp:param> 標(biāo)準(zhǔn)操作,向被包含頁(yè)提供了三個(gè)參數(shù)(a、b 和 c)。被包含的 content.jsp 頁(yè)利用 ${param.a}、${param.b} 和 ${param.c} 輸出三個(gè)參數(shù)的值。 main.jsp <%@ include file="header.jspf" %> <jsp:include page="content.jsp"> <jsp:param name="a" value="1"/> <jsp:param name="b" value="2"/> <jsp:param name="c" value="3"/> </jsp:include> <%@ include file="footer.jspf" %> header.jspf <p> Header </p> footer.jspf <p> Footer </p> content.jsp <p> Included Content </p> <p> Parameters - ${param.a}, ${param.b}, ${param.c} </p> 基于標(biāo)記文件的示例。本示例的 JSP 頁(yè) (main.jsp) 使用 <%@taglib%> 指示語(yǔ)句來(lái)聲明包含標(biāo)記文件 (wrapper.tag) 的庫(kù),指出其前綴 (tags) 以及創(chuàng)建標(biāo)記文件的目錄 (/WEB-INF/tags)。main.jsp 頁(yè)使用 <tags:wrapper> 自定義標(biāo)記來(lái)調(diào)用 wrapper.tag 文件,該標(biāo)記具有三個(gè)屬性(a、b 和 c)和一些主體內(nèi)容 (<p> Wrapped Content </p>)。注意,您在 JSP 頁(yè)的 <tags:wrapper> 與 </tags:wrapper> 之間可以不使用任何腳本編制元素。腳本編制元素包括 JSP 1.x 聲明 (<%!...%>)、JSP 1.x 表達(dá)式 (<%=...%>) 和 scriptlet (<%...%>),而 JSP 2.0 支持所有這些元素。注意,標(biāo)記文件可以象任何常規(guī) JSP 頁(yè)一樣使用腳本編制元素。實(shí)際上,如果您不喜歡基于 Java 標(biāo)記處理程序來(lái)創(chuàng)建 JSP 庫(kù),那么將 Java 代碼從現(xiàn)有的 JSP 頁(yè)移到標(biāo)記文件中會(huì)是個(gè)不錯(cuò)的辦法。這會(huì)使您的 Java scriptlet 可以被重用,并使您的 Web 頁(yè)更易讀。JSP 容器為您完成繁重的工作,它自動(dòng)生成標(biāo)記處理程序類(lèi)。 wrapper.tag 文件是前面示例中三個(gè)被包含頁(yè)(header.jspf、footer.jspf 和 content.jsp)的替代品。標(biāo)記文件使用 <%@attribute%> 指示語(yǔ)句聲明三個(gè)屬性,并輸出一個(gè)標(biāo)題、一個(gè)頁(yè)腳以及屬性的值(${a}、$ 和 ${c})。wrapper.tag 文件利用新的 <jsp:doBody> 標(biāo)準(zhǔn)操作,執(zhí)行 main.jsp 的 <tags:wrapper> 的主體。標(biāo)記文件決定是否執(zhí)行以及何時(shí)執(zhí)行 <tags:wrapper> 的主體。如果 wrapper.tag 不使用 <jsp:doBody>,則忽略 <tags:wrapper> 的主體。標(biāo)記文件還可以多次使用 <jsp:doBody>,以便多次執(zhí)行該主體。 main.jsp <%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> <tags:wrapper a="1" b="2" c="3"> <p> Wrapped Content </p> </tags:wrapper> wrapper.tag <%@ tag body-content="scriptless" %> <%@ attribute name="a" required="true" %> <%@ attribute name="b" required="true" %> <%@ attribute name="c" required="true" %> <p> Header </p> <jsp:doBody/> <p> Attributes - ${a}, $, ${c} </p> <p> Footer </p> 標(biāo)記文件對(duì)比于 <jsp:include> 和 <%@include%>。調(diào)用標(biāo)記文件的自定義標(biāo)記具有比 <jsp:include> 與 <jsp:param> 的組合更緊密的語(yǔ)法。自定義標(biāo)記還能以自然的方式進(jìn)行嵌套和縮進(jìn),使得代碼易于閱讀。唯一可能感覺(jué)不便的方面是一項(xiàng)限制,不允許您在調(diào)用標(biāo)記文件的自定義標(biāo)記主體中使用腳本編制元素??紤]到無(wú)腳本的 Web 頁(yè)可能更易于維護(hù),實(shí)際上這也許是 |
|