JavaWeb之EL和自定義標(biāo)簽

EL 表達(dá)式

使用它可以極大的便利 JSP 頁(yè)面中的數(shù)據(jù)獲取和處理

語(yǔ)法結(jié)構(gòu)

所有的 EL 都是以 ${ 為起始,以 } 為結(jié)尾?

EL 變量

${username} 表示取出某一范圍內(nèi)名稱(chēng)為 username? 的變量,因?yàn)榇藭r(shí)并沒(méi)有指定哪個(gè)范圍的 username,所以它的默認(rèn)情況下會(huì)先從 Page 范圍找,如果找不到,會(huì)依次從 Request、Session、Application 范圍,直到找到值回傳,如果沒(méi)找到,返回 null。

案例

在 testel.jsp 頁(yè)面中,首先在頭部需要注明開(kāi)啟 EL 表達(dá)式:

當(dāng)前頁(yè)面存取 session 值

1、

運(yùn)行結(jié)果:

以上取值方式等同于:

方式一針對(duì)某個(gè)范圍內(nèi)進(jìn)行查找,而方式二沒(méi)有指定,則默認(rèn)從 Page 開(kāi)始查找。

注意:

如果在存 session 的 key 里面含有特殊字符,則應(yīng)使用 [] 來(lái)取值

2、

由圖,新建一個(gè)用戶實(shí)體,分別設(shè)置屬性,并取值。

3、

提交表單數(shù)據(jù)并當(dāng)前頁(yè)面并顯示:

執(zhí)行結(jié)果:

方式一采用的以往通過(guò) JSP 內(nèi)置對(duì)象的 request 來(lái)獲取參數(shù),而方式二采用 EL 表達(dá)式來(lái)獲取,

4、

執(zhí)行結(jié)果

由結(jié)果得知,EL 可以自動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換

EL 隱含對(duì)象

與范圍有關(guān)的:

applicationScope、sessionScope、requestScope、pageScope

與輸入有關(guān)的:

param、paramValues

其他隱含對(duì)象:

cookie、header、headerValues、initParam、pageContext

對(duì)于?pageContext 對(duì)象:

即為 PageContext 類(lèi)型,但只能讀取屬性就可以一直“.”下去

由圖可以獲取相關(guān)等屬性

Empty 屬性

可以作用于一個(gè)集合,若集合不存在或者集合沒(méi)有元素,則結(jié)果為 true

自定義標(biāo)簽

概念:

用戶定義的一種自定義的 JSP 標(biāo)記,當(dāng)一個(gè)含有自定義標(biāo)簽的 JSP 頁(yè)面被 JSP 引擎編譯成 Servlet 時(shí),tag 標(biāo)簽被轉(zhuǎn)化成了對(duì)一個(gè)稱(chēng)為標(biāo)簽處理類(lèi)的對(duì)象的操作。所以,當(dāng) JSP 頁(yè)面被 JSP 引擎轉(zhuǎn)化成 Servlet 后,實(shí)際上 tag 標(biāo)簽被轉(zhuǎn)化為對(duì) tag 處理類(lèi)的操作。使用自定義標(biāo)簽可以降低 JSP 開(kāi)發(fā)的復(fù)雜度和維護(hù)量

編寫(xiě)自定義標(biāo)簽:

核心是編寫(xiě)處理類(lèi),一個(gè)標(biāo)簽對(duì)應(yīng)一個(gè)標(biāo)簽處理器類(lèi),而一個(gè)標(biāo)簽庫(kù)則是很多標(biāo)簽處理器的集合,所有標(biāo)簽處理器都要實(shí)現(xiàn) JspTag 接口,該接口中沒(méi)有定義任何方法,主要作為 Tag 和 SimpleTag 接口的父接口。

標(biāo)簽形式:

1、空標(biāo)簽:<hello/>

2、帶有屬性的空標(biāo)簽:<max num1="3" num2="5"/>

3、帶有內(nèi)容的標(biāo)簽:<greeting>hello</greeting>

4、帶有內(nèi)容和屬性的標(biāo)簽:<greeting name="tom">hello<greeting/>

編寫(xiě)步驟:

1、表寫(xiě)完成標(biāo)簽功能的 java 類(lèi)(標(biāo)簽處理器)

2、編寫(xiě)標(biāo)簽庫(kù)描述(tld)文件,在 tld 文件中對(duì)自定義標(biāo)簽進(jìn)行描述

3、在 JSP 頁(yè)面中導(dǎo)入和使用自定義標(biāo)簽

案例:

確保項(xiàng)目中已導(dǎo)入如下 jar 包:

在 tag 包下新建?HelloSimpleTag 標(biāo)簽處理器類(lèi)并實(shí)現(xiàn)?SimpleTag

然后在 WEB-INF 下新建 mytag.tld 配置文件

頭部信息與 core 一致

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"

? ? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

? ? ? ? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

? ? ? ? version="2.0">

完成以上步驟后在 JSP 引用該 tag

通過(guò)引用,可以對(duì)照 mytag.tld 的配置文件說(shuō)明。

重啟 tomcat

通過(guò)運(yùn)行結(jié)果可以看出,執(zhí)行了?HelloSimpleTag 里的?setJspContext 方法和?doTag 方法。

實(shí)現(xiàn) SimpleTag 接口的標(biāo)簽處理類(lèi)的生命周期:

1、setJspContext

JSP 引擎將代表 JSP 頁(yè)面的 pageContext 對(duì)象傳遞給標(biāo)簽處理器對(duì)象

2、setParent

JSP 引擎將父標(biāo)簽處理器對(duì)象傳遞給當(dāng)前標(biāo)簽處理器對(duì)象。只有存在父標(biāo)簽時(shí),JSP 引擎才會(huì)調(diào)用該方法

3、setXXX?

設(shè)置標(biāo)簽屬性,只要定義屬性才調(diào)用該方法

4、setJspBody?

若存在標(biāo)簽體,JSP 引擎將把標(biāo)簽體封裝成一個(gè) JspFragment 對(duì)象,調(diào)用?setJspBody 方法將 JspFragment 對(duì)象傳遞給標(biāo)簽處理器對(duì)象,若標(biāo)簽體為空?setJspBody? 將不會(huì)被 JSP 引擎調(diào)用

5、doTag

容器調(diào)用標(biāo)簽處理器對(duì)象的 doTag 方法執(zhí)行標(biāo)簽邏輯

對(duì)于?setJspContext,在方法里把 jspContext 對(duì)象賦予全局變量 pageContext,這樣就能獲取到 JSP 中的所有隱含對(duì)象。

編寫(xiě)帶屬性的標(biāo)簽

首先,在 tld 配置文件下添加如下內(nèi)容

注:rtexprvalue 表示的是 runtime expression value

然后在?HelloSimpleTag 類(lèi)下添加兩個(gè)成員變量 value 和 count 用來(lái)接收參數(shù),強(qiáng)烈建議使用 String 類(lèi)型的參數(shù),并且實(shí)現(xiàn)兩者的 set 方法。

接著在 doTag 里面獲取參數(shù),并且進(jìn)行邏輯處理

最后在 JSP 里面引用標(biāo)簽

如果是接收動(dòng)態(tài)值可以這么寫(xiě)

如果重新新建了 tag 類(lèi),只需在 tld 配置文件里面重新添加 tag 標(biāo)簽,并進(jìn)行屬性的說(shuō)明

通常情況下,開(kāi)發(fā)簡(jiǎn)單標(biāo)簽直接繼承?SimpleTagSupport 就可以,可以直接調(diào)用其對(duì)應(yīng)的 getter 方法得到對(duì)應(yīng)的 API

編寫(xiě)帶標(biāo)簽體的自定義標(biāo)簽

1、在自定義標(biāo)簽的標(biāo)簽處理器中使用 JspFragment 對(duì)象封裝標(biāo)簽體信息

2、若配置了標(biāo)簽含有標(biāo)簽體,則 JSP 引擎會(huì)調(diào)用 setJspBody() 方法把 JspFragment 傳遞給標(biāo)簽處理類(lèi),在 SImpleTagSupport 中還定義了一個(gè) getJspBody() 方法,用于返回 JspFragment 對(duì)象

3、JspFragment 的 invoke(writer)方法:把標(biāo)簽體內(nèi)容從 Writer 中輸出,若為 null,則等同于 invoke(getJspContext().getOut()),即直接把標(biāo)簽體內(nèi)容輸出到頁(yè)面上

4、在 tld 文件中,使用 body-content 節(jié)點(diǎn)來(lái)描述標(biāo)簽體的類(lèi)型:

empty:沒(méi)有標(biāo)簽體

scriptless:標(biāo)簽體可以包含 el 表達(dá)式和 JSP 動(dòng)作元素,但不能包含 JSP 的腳本元素

說(shuō)明:

由圖,第一種屬于 el 表達(dá)式,第二種表示 JSP 腳本元素。

tagdependent:表示標(biāo)簽體交由標(biāo)簽本身去解析處理,若指定?tagdependent,在標(biāo)簽體中的所有代碼都會(huì)原封不動(dòng)的交給標(biāo)簽處理器,而不是將執(zhí)行結(jié)果傳遞給標(biāo)簽處理器

大部分情況下,類(lèi)型取值為?scriptless

如圖,獲取標(biāo)簽體的內(nèi)容,并轉(zhuǎn)換成大寫(xiě)打印在頁(yè)面上

編寫(xiě)帶父標(biāo)簽的自定義標(biāo)簽

編寫(xiě)一個(gè)父標(biāo)簽?TestParentTag,并編寫(xiě)一個(gè)子標(biāo)簽?TestSonTag,在 JSP 引用的時(shí)候,父標(biāo)簽在控制臺(tái)打印信息,子標(biāo)簽作為父標(biāo)簽的標(biāo)簽體在頁(yè)面上顯示父標(biāo)簽的內(nèi)容

TestParentTag:

TestSonTag:

tld 配置:

JSP 引用:

運(yùn)行結(jié)果:

通過(guò)案例可以得出:

1、父標(biāo)簽無(wú)法獲取子標(biāo)簽的引用,父標(biāo)簽僅把子標(biāo)簽作為標(biāo)簽體來(lái)使用

2、子標(biāo)簽可以通過(guò) getParent() 來(lái)獲取父標(biāo)簽的引用(需繼承 SimpleTagSupport 或?qū)崿F(xiàn) SimpleTag 接口的該方法),若子標(biāo)簽的確有父標(biāo)簽,JSP 引擎會(huì)把代表父標(biāo)簽的引用通過(guò) setParent(JspTag parent) 賦給標(biāo)簽處理器

3、父標(biāo)簽的類(lèi)型是 JspTag 類(lèi)型,該 JspTag 接口為空接口,用來(lái)統(tǒng)一?SimpleTag 和 Tag 的,簡(jiǎn)單標(biāo)簽和傳統(tǒng)標(biāo)簽

4、在 tld 配置文件中,不需要為父標(biāo)簽有額外的配置,但子標(biāo)簽是以標(biāo)簽體的形式存在的,所以父標(biāo)簽的 body-content 需要設(shè)置為?scriptless

JSTL fn 函數(shù)

為了簡(jiǎn)化在 JSP 頁(yè)面操作字符串,JSTL 中提供了一套 EL 自定義函數(shù),這些自定義函數(shù)包含了 JSP 頁(yè)面經(jīng)常用到的字符串操作

使用方法如下:

如圖,在頭部引用函數(shù)的聲明,然后通過(guò)?${fun:contains("name", "a")} 來(lái)操作字符串



以上為本人的一些學(xué)習(xí)筆記,如有出錯(cuò)歡迎指正,陸續(xù)更新?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容