自定義標簽可以實現的功能:
- 移除jsp中的java代碼
- 控制jsp中的某段程序是否執行
- 控制jsp頁面中的所有內容是否執行
- 控制jsp中的程序重復執行
- 修給jsp中的內容。
傳統標簽庫 總結:
創建傳統標簽
- 創建jsp標簽類繼承
TagSupport
類。 - 重寫
doStartTag()
方法,在doStartTag()
方法中書寫程序,此方法在執行開始標簽的時候被服務器調用。服務器在遇到標簽的時候先調用tag類的setPageContext(pageContext)
方法將pageContext類傳遞進去。 - 在WEB-INF下創建tld文件,在文件中對標簽進行配置。
<?xml version="1.0" encoding="UTF-8" ?>
<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">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
//將此標簽綁定的uri,通過此uri引用標簽
<uri>http://www.baixinping.com</uri>
<tag>
<description>Outputs Hello, World</description>
//引用時的名稱
<name>ha</name>
//標簽類的目錄
<tag-class>baixinping.tag.Ha</tag-class>
//標簽體中是否有內容
<body-content>empty</body-content>
</tag>
</taglib>
- 使用:
<%@ taglib uri="http://www.baixinping.com" prefix="ha" %>
控制jsp中的某段程序的輸出:
1、繼承TagSupport
2、重寫doStartTag();
3、如果doStartTag()
返回TagSupport.SKIP_BODY
,則不執行標簽體中的內容,如果返回的是TagSupport.EVAL_BODY_INCLUDE
則執行標簽體中的內容。
控制jsp頁面是否執行。
- 繼承
TagSupport
- 重寫
doEndStart()
- 如果
doEndTag()
返回TagSupport.SKIP_PAGE
,則不執行余下的jsp中的內容。如果返回TagSupport.EVAL_PAGE
,則繼續執行余下的內容。
控制部分代碼重復執行
- 繼承繼承
TagSupport
- 重寫
doAfterBody()
方法,此方法在執行完標簽體中的內容之后執行。 - 如果
doAfterBody()
方法返回TagSupport.EVAL_BODY_AGAIN
,則繼續執行標簽體中的內容。如果返回TagSupport.SKIP_BODY
則繼續執行doEndTag()
方法。
修改jsp中的內容
- 繼承
BodyTagSupport
。此類在執行完doStartTag()
完之后會自動執行setBodyContent()
方法將標簽體中的內容傳遞給標簽類。然后執行doEndTag
方法。 - 在
doEndTag()
方法中通過this.getBodyContent()
獲取標簽體內容對象,然后對其進行修改即可。
簡單標簽庫使用 總結:
繼承SimpleTagSupport
。tld文件中聲明有標簽體使用<body-content>scriptless</body-content>
,意思是標簽體中不能有腳本代碼(java程序)
簡單標簽執行步驟(原理):
- 遇到簡單標簽之后,先實例化標簽類。
- 調用
setJspContext()
將pageContexr()
將jsp頁面對象傳遞過來。 - 調用
setParent()
方法將標簽的父標簽傳遞過來,如果沒有父標簽傳遞null. - 調用
setJspBody()
將封裝了標簽體內容的JspFragment
對象傳遞過來。 - 執行標簽(調用
doTag()
方法),控制標簽之后的內容不被執行,只需要拋出new SkipPageException()
即可。
JspFragment content = this.getJspBody();
content.invoke(this.getJspContext().getOut());
使用invoke()方法將內容寫入對應的流緩沖區中。 - 垃圾回收器回收標簽對象(在傳統標簽中,標簽對象會駐留在內存中繼續服務之后的調用)
標簽定義屬性:
- 在標簽類中創建屬性值,并創建set方法。
- 在tld文件中聲明屬性。
<tag>
<description>Outputs Hello, World</description>
<name>test6</name>
<tag-class>baixinping.tag.Test6</tag-class>
<body-content>scriptless</body-content>
<attribute>
//屬性名
<name>count</name>
//屬性是否必須
<required>true</required>
//屬性值是否可以使用表達式
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
注意:set方法會自動有服務器調用,服務器賦值只能夠進行8中基本數據類型轉換。若是復雜類型,則在jsp頁面中使用表達式。