日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JSP 最佳實踐: taglib簡介

 duduwolf 2005-09-23
將scriptlet轉(zhuǎn)換成自定義標記以獲得更好的JSP代碼

Brett McLaughlin
作者, O‘Reilly and Associates
2003 年 9 月 28 日

Scriptlet對于快而雜(fast-and-dirty)的編碼來說是一種不錯的選擇,但是從長遠來看,您需要為您的JSP頁面選擇一種不那么雜亂的解決方案。在本期的 JSP最佳實踐中,BrettMcLaughlin 向您展示了如何將scriptlet轉(zhuǎn)化成JSP自定義標記,然后將其用于您的JSP開發(fā)中。

JSP最佳實踐上一期,您學習了一種基于scriptlet的技術(shù),這種技術(shù)被用來將上次修改的時間戳添加到JavaServer Page(JSP)文件中。不幸的是,比起它所提供的短期利益,scriptlet會將更多的長期復雜性引入到您的頁面中來。這些scriptlet會用Java代碼將各種類型的HTML混雜在一起,從而使得程序的調(diào)試和設計極其錯綜復雜。scriptlet不能重用,這常常導致開發(fā)者不得不在JSP頁面之間進行復制-粘貼操作,進而導致同一段代碼出現(xiàn)多個版本。而且,scriptlet還加大了錯誤處理的難度,因為JSP沒有提供干凈利落的方式來報告腳本錯誤。

因此,這次我們將設計一種新的解決方案。在本期的 JSP最佳實踐中,您將學習一些基礎知識,主要是關于如何將scriptlet轉(zhuǎn)換成自定義標記,并對其進行設置以便在您的JSP開發(fā)項目中使用。

為什么使用taglib?
所謂 標記庫(tag library),是指由在JSP頁面中使用的標記所組成的庫。JSP容器推出時帶有一個小型的、默認的標記庫。而 自定義標記庫是人們?yōu)榱四撤N特定的用途或者目的,將一些標記放到一起而形成的一種庫。在一個團隊中協(xié)同工作的開發(fā)者們可能會為各自的項目創(chuàng)建一些非常特定化的自定義標記庫,同時也會創(chuàng)建一個通用自定義標記庫,以供當前使用。

JSP 標記替代了scriptlet,并緩解了由scriptlet所招致的所有令人頭痛的事情。例如,您可以看到這樣的標記:

<store:shoppingCart id="1097629"/>

或者這樣的標記:

<tools:usageGraph />

每個標記都包含了指向一個Java類的引用,但是類中的代碼仍然在它該在的地方:在標簽之外,一個編譯好的類文件之中。

從 scriptlet 到標記
創(chuàng)建一個自定義標記的第一步就是決定您想怎樣使用它,如何稱呼它,以及它允許使用或者需要什么屬性(如果有的話)。對于時間戳標記,我們所需要的很簡單:只要一個能夠輸出一個頁面的最后修改數(shù)據(jù)的簡單標記。

因為不需要屬性,這個標記看上去就是這個樣子:

<site-utils:lastModified />

這個標記的名稱和前綴是一樣的:都是 site-utils 。元素的內(nèi)容是空的,這意味著該元素中不允許有子元素存在。定義了這個標記之后,接下來的一步就是實現(xiàn)它的行為。

實現(xiàn)行為
實現(xiàn)標記行為的第一步是將scriptlet代碼從原先所在的地方移到一個Java類( LastModifiedTag )中,如清單 1 所示:

清單 1. 創(chuàng)建一個時間戳標記

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    public int doEndTag() {
      try {
        HttpServletRequest request =
(HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);

        DateFormat formatter = DateFormat.getDateInstance(
          DateFormat.LONG);

        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}

這個方法中的代碼看上去比較熟悉;實質(zhì)上,它正是我們在先前用到的相同的時間戳代碼。由于不需要用戶輸入,而且該標記也沒有屬性或者嵌入的內(nèi)容,我們惟一需要關心的一個新方法就是 doEndTag() (),在這個方法中該標記可以輸出內(nèi)容(在這個例子中是最后修改數(shù)據(jù))到JSP頁面。

清單 1 中其他的更改更多地與作為一個JSP標記的代碼有關,而與在一個頁面內(nèi)運行的scriptlet沒有多大關系。例如,所有的JSP標記都應該擴展JSP類 javax.servlet.jsp.tagext.TagSupport ,這個類為JSP標記提供了基本框架。可能您還注意到,該標記返回的 EVAL_PAGE . EVAL_PAGE 是一個預定義的整型常量,它指示容器處理頁面的剩下部分。另一種選項就是使用 SKIP_PAGE ,它將中止對頁面剩下部分的處理。如果您要將控制轉(zhuǎn)移到另一個頁面,例如您要前進(forward)或者重定向(redirect)用戶,那么只需要使用 SKIP_PAGE 。剩下來的細節(jié)都是與時間戳自身有關的事情。

接下來,編譯這個類,并將 LastModifiedTag.class 文件放到一個WEB-INF/classes 目錄下,注意要放到正確的路徑層次結(jié)構(gòu)中。這個路徑應該匹配該標記的包名,包名中的圓點(.)用斜杠(/)代替。在本例中,目錄的路徑是基路徑(WEB-INF/classes)再加上層次結(jié)構(gòu)com/newInstance/site/tags。如果有一個名為 foo.bar.tag.MyTag 的標記,那么它將被放在 WEB-INF/classes/foo/bar/tag中。這種路徑層次結(jié)構(gòu)確保了Web容器在任何需要裝載該標記的時候都能夠找到這個類。

創(chuàng)建TLD
接下來的一步是創(chuàng)建一個 標記庫描述符(tag library descriptor ,TLD)文件。TLD向容器和任何要使用該標記庫的JSP頁面描述您的標記庫。清單 2 顯示了一個非常標準的TLD,其中只包含了一個標記。當您將更多的標記添加到庫中時,TLD文件的長度和復雜性將隨之增長。

清單 2. 一個標記庫描述符

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib
    PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2/EN"
           "http://java./dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>site-utils</short-name>
    <uri>http://www.newInstance.com/taglibs/site-utils</uri>

    <tag>
      <name>lastModified</name>
      <tag-class>com.newInstance.site.tags.LastModifiedTag</tag-class>
      <body-content>empty</body-content>
    </tag>
</taglib>

TLD 文件頂部的信息應用于整個標記庫。在本例中,我提供了一個版本(這對于跟蹤某個標記庫的JSP創(chuàng)建者擁有哪個版本很有用,尤其是在您需要經(jīng)常修改標記庫的情況下更是如此);該標記庫所依賴的JSP版本;一個為該標記庫推薦的前綴;以及用于引用這個標記庫的URI。注意,我使用了前綴 short-name 作為URI的一部分,這樣 比較容易將前綴和標記庫的URI看成一個整體。

剩下的信息用于一個特定的標記,這些信息用 tag 元素表示。我指定了該標記的名稱、用于該標記的類(這個類應該被編譯好并放在適當?shù)牡胤?,以便容器能夠裝載),最后還指定了該標記是否有嵌入的內(nèi)容。在本例中,標記沒有嵌入的內(nèi)容,因此使用"empty"。

保存這個文件,并將其放到WEB-INF/tlds目錄下(您可能需要在您的容器中創(chuàng)建這個目錄)。我將這個文件保存為site-utils.tld,并在該標記庫的URI(推薦的前綴)和TLD文件本身之間再次創(chuàng)建一個干凈的鏈接。對于這個特定的標記庫,要使其可以使用,最后一步要做的是讓您的Web應用知道如何連接一個JSP頁面中的URI,如何請求使用一個標記庫。這可以通過應用的web.xml文件來做。清單 3 顯示了一個非常簡單的web.xml片段,正是它為我們的標記庫做這樣的事情。

清單 3. 將一個URI與一個標記庫鏈接起來

<taglib>
      <taglib-uri>http://www.newInstance.com/taglibs/site-utils</taglib-uri>
      <taglib-location>/WEB-INF/tlds/site-utils.tld</taglib-location>
    </taglib>

包裝起來
如果您已經(jīng)按照上述步驟執(zhí)行了,那么現(xiàn)在您應該能夠在JSP頁面中引用新標記了。清單 4 向我們展示了新改進的footer.jsp,這個文件中現(xiàn)在完全沒有scriptlet,也沒有指向具有scriptlet的JSP頁面的引用。

清單 4. 使用新的標記庫

<%@ taglib prefix="site-utils"
             uri="http://www.newInstance.com/taglibs/site-utils" %>
          </td>
          <td width="16" align="left" valign="top"> </td>
    </tr>
    <!-- End main content -->

<!-- Begin footer section -->
    <tr>
      <td width="91" align="left" valign="top" bgcolor="#330066"> </td>
      <td align="left" valign="top"> </td>
      <td class="footer" align="left" valign="top"><div align="center"><br>
        &copy; 2003 
        <a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
        Last Updated: <site-utils:lastModified />
        </div></td>
      <td align="left" valign="top"> </td>
      <td width="141" align="right" valign="top" bgcolor="#330066"> </td>
    </tr>
</table>
<!-- End footer section -->

在前面幾期中看了JSTL如何工作(參見“ 利用JSTL更新您的JSP頁面”和“ 導入內(nèi)容到您的Web站點”)之后,接下來該做什么您應該很清楚了:我們通過使用web.xml文件中的URI來引用這個標記庫,為之分配一個前綴(來自TLD的 short-name 始終是最好的選擇),然后就像使用任何其他JSP標記一樣使用這個標記。最終得到的是一個簡潔的、更好的JSP頁面,這個JSP頁面運行起來不比有 scriptlet 的時候差。

當前我們的自定義標記還很簡單,在下一期,我們將擴展其功能。到時候網(wǎng)上見。

參考資料

關于作者
Photo of Brett McLaughlinBrett McLaughlin 自Logo時期(還記得那個小三角形嗎?)起就從事計算機方面的工作。目前,他專攻使用Java和Java相關的技術(shù)構(gòu)建應用基礎設施。最近幾年,他一直在Nextel Communications and Allegiance Telecom公司,致力于實現(xiàn)這些基礎設施。Brett是Java Apache項目Turbine的合創(chuàng)者之一,Turbine為使用Java servlets的Web應用的開發(fā)構(gòu)建了可重用組件基礎設施。對于EJBoss項目(一種開源EJB應用服務器)和Cocoon(一種開源XML Web發(fā)布引擎),他也作出了貢獻。您可以通過 brett@與Contact Brett 聯(lián)系。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多