jsp自訂標籤

來源:互聯網
上載者:User

jsp頁面標籤定義:

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

清單 1. 建立一個時間戳記標記
package com.jrcz.aura.util;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;
/*
 * 編寫標籤對應的實作類別時,需要重載BodyTagSupport類幾個方法:doStartTag(), setBodyContent(),
 * doInitBody(), doAfterBody(), doEndTag(); 
 * 他們執行順序如下:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()
 * doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,如果返回EVAL_BODY_INCLUDE則繼續執行;
 * 如果返回SKIP_BODY則接下來的doInitBody(),setBodyContent(), doAfterBody()三個方法不會被執行,
 *  而直接執行doEndTag()方法   
 *  setBodyContent()方法用於設定標籤體內容,如果在此之前要作一些初始化工作,則在doInitBody()方法中完成
 *  標籤體內容執行完後,會調用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY, EVAL_PAGE或SKIP_PAGE。
 *  如果返回EVAL_BODY_TAG則會再次設定標籤體內容,直到返回SKIP_BODY;
 *  如果返回EVAL_PAGE則標籤體執行完後會繼續執行JSP頁面中接下來的部分;
 *  如果返回SKIP_PAGE,則JSP頁面的後續內容將不再執行。
 *  標籤中靜態常量:
    EVAL_BODY_INCLUDE:告訴伺服器本文的內容,並把這些內容送入輸出資料流
    SKIP_BODY:告訴伺服器不要處理本文內容
 EVAL_PAGE:讓伺服器繼續執行頁面
 SKIP_PAGE:讓伺服器不要處理剩餘的頁面
 EVAL_BODY_AGAIN:讓伺服器繼續處理本文內容,只有doAfterBody方法可以返回
 EVAL_BODY_BUFFERED:BodyTag介面的欄位,在doStartTag()返回
 EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回。
 */
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())));
  pageContext.getOut().println("你好你好");
  System.out.println("path:"+path);
  } catch (IOException e) {
   e.printStackTrace();
  }
  return EVAL_PAGE;
 }

}

這個方法中的代碼看上去比較熟悉;實質上,它正是我們在先前用到的相同的時間戳記代碼。由於不需要使用者輸入,而且該標記也沒有屬性或者嵌入的內容,我們惟一需要關心的一個新方

法就是 doEndTag() (),在這個方法中該標記可以輸出內容(在這個例子中是最後修改資料)到JSP頁面。
清單 1 中其他的更改更多地與作為一個JSP標記的代碼有關,而與在一個頁面內啟動並執行scriptlet沒有多大關係。例如,所有的JSP標記都應該擴充JSP類

javax.servlet.jsp.tagext.TagSupport ,這個類為JSP標記提供了基本架構。可能您還注意到 ,該標記返回的 EVAL_PAGE . EVAL_PAGE 是一個預定義的整型常量,它指示容器處理頁面

的剩下部分。另一種選項就是使用 SKIP_PAGE ,它將中止對頁面剩下部分的處理。如果您要將控制轉移到另一個頁面,例如您要前進(forward)或者重新導向(redirect)使用者,那麼只

需要使用 SKIP_PAGE 。剩下來的細節都是與時間戳記自身有關的事情。
接下來,編譯這個類,並將 LastModifiedTag.class 檔案放到一個WEB-INF/classes 目錄下,注意要放到正確的路徑階層中。這個路徑應該匹配該標記的包名,包名中的圓點(.)

用斜杠(/)代替。在本例中,目錄的路徑是基路徑(WEB-INF/classes)再加上階層com/newInstance/site/tags。如果有一個名為 foo.bar.tag.MyTag 的標記,那麼它將被放在

WEB-INF/classes/foo/bar/tag中。這種路徑階層確保了Web容器在任何需要裝載該標記的時候都能夠找到這個類。
回頁首
建立TLD
接下來的一步是建立一個 標記庫描述符(tag library descriptor ,TLD)檔案。TLD向容器和任何要使用該標記庫的JSP頁面描述您的標記庫。清單 2 顯示了一個非常標準的TLD,其中

只包含了一個標記。當您將更多的標記添加到庫中時,TLD檔案的長度和複雜性將隨之增長。

清單 2. 一個標記庫描述符
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE taglib
    PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2/EN"
           "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>gpb</short-name>
    <uri>http://www.newInstance.com/taglibs/site-utils</uri>
    <tag>
      <name>lastModified</name>
      <tag-class>com.jrcz.aura.util.LastModifiedTag</tag-class>
      <body-content>empty</body-content>
    </tag>
</taglib>

TLD 檔案頂部的資訊應用於整個標記庫。在本例中,我提供了一個版本(這對於跟蹤某個標記庫的JSP建立者擁有哪個版本很有用,尤其是在您需要經常修改標記庫的情況下更是如此);

該標記庫所依賴的JSP版本;一個為該標記庫推薦的首碼;以及用於引用這個標記庫的URI。注意,我使用了首碼 short-name 作為URI的一部分,這樣 比較容易將首碼和標記庫的URI看成

一個整體。
剩下的資訊用於一個特定的標記,這些資訊用 tag 元素表示。我指定了該標記的名稱、用於該標記的類(這個類應該被編譯好並放在適當的地方,以便容器能夠裝載),最後還指定了該

標記是否有嵌入的內容。在本例中,標記沒有嵌入的內容,因此使用"empty"。
儲存這個檔案,並將其放到WEB-INF/tlds目錄下(您可能需要在您的容器中建立這個目錄)。我將這個檔案儲存為site-utils.tld,並在該標記庫的URI(推薦的首碼)和TLD檔案本身之

間再次建立一個乾淨的連結。對於這個特定的標記庫,要使其可以使用,最後一步要做的是讓您的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>

回頁首
封裝起來
如果您已經按照上述步驟執行了,那麼現在您應該能夠在JSP頁面中引用新標記了。清單 4 向我們展示了新改進的footer.jsp,這個檔案中現在完全沒有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 -->
<div id="divab"></div>
  <div>自訂標籤</div>
  <gpb:lastModified />

在前面幾期中看了JSTL如何工作(參見“ 利用JSTL更新您的JSP頁面”和“ 匯入內容到您的Web網站”)之後,接下來該做什麼您應該很清楚了:我們通過使用web.xml檔案中的URI來引

用這個標記庫,為之分配一個首碼(來自TLD的 short-name 始終是最好的選擇),然後就像使用任何其他JSP標記一樣使用這個標記。最終得到的是一個簡潔的、更好的JSP頁面,這個

JSP頁面運行起來不比有 scriptlet 的時候差。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.