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

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

BodyTag接口用法詳細(xì)介紹

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

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


1. EVAL_BODY_BUFFERED常量

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


2. setBodyContent(BodyContent b)方法

當(dāng)且僅當(dāng)doStartTag()方法返回EVAL_BODY_BUFFERED常量時(shí),JSP容器才會(huì)調(diào)用setBodyContent()方法,通過該方法將BodyContent對象傳遞給標(biāo)簽處理器類使用。


3. dolnitBody()方法

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

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

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

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

BodyContent類的常用方法

方法聲明

功能描述

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

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

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

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

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

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


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

JSP規(guī)范中定義了一個(gè)類BodyTagSupport實(shí)現(xiàn)了BodyTag接口,為了簡化程序的編寫,標(biāo)簽處理器類ToUpperCase.java只需要繼承BodyTagSupport類即可。ToUpperCase.java類的實(shí)現(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ù)轉(zhuǎn)為大寫
        content = content.toUpperCase();
        try{
            //輸出數(shù)據(jù)內(nèi)容(兩種方式均可)
            //pageContext.getout().write(content);
            bodyContent.getEnclosingWriter().write(content);
        } catch(IOException e){
            e.printStackTrace();
            return super.doEndTag();
        }
}

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

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


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

在mytag.tld文件中增加一個(gè)Tag元素,對標(biāo)簽處理器類進(jìn)行注冊,注冊信息如下所示。

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

(3)編寫JSP頁面toUpperCase.jsp

在JSP頁面中使用標(biāo)簽,在標(biāo)簽體中寫人26個(gè)小寫的英文字母,如下例所示。

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

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



猜你喜歡

JSTL標(biāo)簽是什么?常用的有哪些?

Java中的線程池有哪些?

java線程休眠的sleep方法詳細(xì)介紹

傳智教育Java培訓(xùn)課程

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