教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

BodyTag接口用法詳細介紹

更新時間:2021年11月22日11時07分 來源:傳智教育 瀏覽次數(shù):

在實現(xiàn)自定義標簽時,有時需要對標簽體的內容進行處理以后再向瀏覽器輸出,比如將小寫英文字母轉化為大寫,將HTML標簽進行轉義等。為了實現(xiàn)這樣的功能,JSP規(guī)范中它義了一個BodyTag接口,它繼承自IterationTag接口,并在IterationTag接口基礎上新增了兩個方法和一個靜態(tài)常量,具體如下。


1. EVAL_BODY_BUFFERED常量

如果標簽處理器類實現(xiàn)了BodyTag接口,它的doStartTag()方法除了可以返回SKIP_BODY和EVAL_BODY_INCLUDE常量之外,還可以返回EVAL_BODY_BUFFERED常量。當doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器將會創(chuàng)建個javax.servlet.jsp.tagext.BodyContent對象,使用該對象來執(zhí)行標簽體。關于BodyContent類的用法,將在下面進行詳細的講解。


2. setBodyContent(BodyContent b)方法

當且僅當doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器才會調用setBodyContent()方法,通過該方法將BodyContent對象傳遞給標簽處理器類使用。


3. dolnitBody()方法

JSP容器在調用setBodyContent()方法后會調用doInitBody()方法來完成些初始化工作,該方法的調用在標簽體執(zhí)行之前。

其中,最重要的是setBodyContent()方法。為了幫助大家更好地理解BodyTag接口處理標簽內容的方式,有必要對BodyContent類進行詳細講解。

BodyContent類是JspWriter類的子類,它在JspWriter的基礎上增加了一個用于存儲數(shù)據(jù)的緩沖區(qū)(確切地說緩沖區(qū)是在BodyContent的子類org.apache.jasper.runtime.BodyContentImple中定義的),當調用BodyContent對象的方法寫數(shù)據(jù)時,數(shù)據(jù)將被寫人到BodyContent內部的緩沖區(qū)中。

明白了BodyContent類的這個特點,就不難理解JSP容器是如何利用BodyContent對象來處理標簽體內容了。當標簽處理器類的doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器會創(chuàng)建一個BodyContent對象,然后調用該對象的write()方法將標簽體的內容寫人BodyContent對象的緩沖區(qū)中,開發(fā)者只要能夠訪問BodyContent緩沖區(qū)的內容,就能對標簽體的內容進行處理。在BodyContent類中定義了一些用于訪問緩沖區(qū)內容的方法,具體如下表所示。

BodyContent類的常用方法

方法聲明

功能描述

String getString() 以字符串的形式返回BodyContent對象緩沖區(qū)中保存的數(shù)據(jù)
Reader getReader() 返回一個關聯(lián)BodyContent對象緩沖區(qū)中數(shù)據(jù)的Reader對
象,通過Reader對象可以讀取緩沖區(qū)中的數(shù)據(jù)
void clearBody() 用于清空BodyContent對象緩沖區(qū)中的內容
JspWriter getEnclosingWriter() 用于返回BodyContent對象中關聯(lián)的JspWriter對象。當JSP容器創(chuàng)建BodyContent對象后,PageContext對象中的"out"屬性不再指向JSP的隱式對象,而是指向新創(chuàng)建的BodyContent對象。同時,在BodyContent對象中會用一個JspWriter類型的成員變量enclosingWriter記住原來的隱式對象,getEnclosingWriter()方 法返回的就是原始的JSP隱式對象
writerOut(Writer out) 用于將BodyContent對象中的內容寫人到指定的輸出流

在上表列舉的所有方法中,其中getEnclosingWriter()方法最難理解,但是,只需要記住該方法的返回值為out即可。

除了BodyContent類外,在BodyTag接口還會涉及很多常量和方法,為了讓大家更好地掌握標簽處理器的執(zhí)行流程,接下來通過一張圖來描述,具體如下圖所示。

標簽處理器的執(zhí)行流程
標簽處理器的執(zhí)行流程

上圖中清楚地描述了JSP容器執(zhí)行標簽處理器的過程。其中,release()方法之所以使用用虛線,是因為這個方法不會在標簽處理器每次執(zhí)行都被JSP容器調用,只有當標簽處理器對象作為垃圾被回收之前它才會被調用。傳統(tǒng)標簽的處理器是單例的,只會被創(chuàng)建和銷毀一次。

接下來,通過實現(xiàn)自定義標簽,學習如何使用BodyTag接口將標簽體中的小寫英文字母轉換為大寫,具體步驟如下。


(1)編寫標簽處理器類ToUpperCase.java。

JSP規(guī)范中定義了一個類BodyTagSupport實現(xiàn)了BodyTag接口,為了簡化程序的編寫,標簽處理器類ToUpperCase.java只需要繼承BodyTagSupport類即可。ToUpperCase.java類的實現(xiàn)代碼如下例所示。

package cn.itcast.chapter09.classisctag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ToUpperCase extends BodyTagSupport {
    //定義doEndTag()方法
    public int doEndTag() throws JspException {
        //獲取級沖區(qū)中數(shù)據(jù)
        String content = getBodyContent().getString();
        //將數(shù)據(jù)轉為大寫
        content = content.toUpperCase();
        try{
            //輸出數(shù)據(jù)內容(兩種方式均可)
            //pageContext.getout().write(content);
            bodyContent.getEnclosingWriter().write(content);
        } catch(IOException e){
            e.printStackTrace();
            return super.doEndTag();
        }
}

由于BodyTagSupport類中的doStartTag()方法默認返回EVAL_BODY_BUFFERED常量,JSP容器會在執(zhí)行標簽體之前創(chuàng)建BodyContent對象,然后將標簽體內容通過setBodyContent()方法設置給BodyContent對象。因此在上面案例中的doEndTag()方法中可以直接使用getBodyContent()方法的getString()方法獲得寫人到BodyContent緩沖區(qū)中的內容,然后將其轉換為大寫,通過調用getEnclosingWriter()方法獲取到out對象,將內容輸出到瀏覽器中。

注意:不能直接使用doStartTag()方法的原因是,執(zhí)行doStartTag()方法時,BodyContent對象中還沒有緩存標簽體的內容,因此通過getBodyContent()方法還無法獲得標簽的內容。


(2)注冊標簽處理器類。

在mytag.tld文件中增加一個Tag元素,對標簽處理器類進行注冊,注冊信息如下所示。

<tag>
    <name>toUpperCase</name>
    <tag-class> cn.itcast.chapter09.classisctag.ToUpperCase</tag-class>
    <body-content>JSP</body-content>
</tag>

(3)編寫JSP頁面toUpperCase.jsp

在JSP頁面中使用標簽,在標簽體中寫人26個小寫的英文字母,如下例所示。

<%@page language="java" pageEncoding="GBK"%>
<%@taglib uri= "http://oisangadgets.com" prefix="itcast"%>
<html>
    <head>
    <title>HelloWorld Tag</title>
</head>
<body>
    <itcast: toUpperCase>
        abcde fghij klmnopqrstuvwxyz
    </itcast:toUpperCase>
</body>
</html>

(4)啟動Tomcat服務器,在瀏覽器地址欄中輸人URL地址“http://localhost:8080/chapter09/toUpperCase.jsp”訪問toUpperCase.jsp頁面,從運行結果可以看出,自定義標簽成功地將標簽體中的小寫英文字母轉換為大寫。



猜你喜歡

JSTL標簽是什么?常用的有哪些?

Java中的線程池有哪些?

java線程休眠的sleep方法詳細介紹

傳智教育Java培訓課程

0 分享到:
和我們在線交談!