一、JspFragment類介紹
javax.servlet.jsp.tagext.JspFragment類是在JSP2.0中定義的,它的實例對象代表JSP頁面中的一段符合JSP語法規范的JSP片段,這段JSP片段中不能包含JSP腳本元素。
WEB容器在處理簡單標簽的標簽體時,會把標簽體內容用一個JspFragment對象表示,並調用標簽處理器對象的setJspBody方法把JspFragment對象傳遞給標簽處理器對象。JspFragment類中只定義了兩個方法,如下所示:
getJspContext方法
用於返回代表調用頁面的JspContext對象.
public abstract void invoke(java.io.Writer out)
用於執行JspFragment對象所代表的JSP代碼片段,參數out用於指定將JspFragment對象的執行結果寫入到哪個輸出流對象中,如果 傳遞給參數out的值為null,則將執行結果寫入到JspContext.getOut()方法返回的輸出流對象中。(簡而言之,可以理解為寫給瀏覽器)
1.1、invoke方法詳解
JspFragment.invoke方法是JspFragment最重要的方法,利用這個方法可以控制是否執行和輸出標簽體的內容、是否迭代執行標簽體的內容或對標簽體的執行結果進行修改后再輸出。例如:
在標簽處理器中如果沒有調用JspFragment.invoke方法,其結果就相當於忽略標簽體內容;
在標簽處理器中重復調用JspFragment.invoke方法,則標簽體內容將會被重復執行;
若想在標簽處理器中修改標簽體內容,只需在調用invoke方法時指定一個可取出結果數據的輸出流對象(例如StringWriter),讓標簽體的執行結果輸出到該輸出流對象中,然后從該輸出流對象中取出數據進行修改后再輸出到目標設備,即可達到修改標簽體的目的。
二、開發帶屬性的標簽
自定義標簽可以定義一個或多個屬性,這樣,在JSP頁面中應用自定義標簽時就可以設置這些屬性的值,通過這些屬性為標簽處理器傳遞參數信息,從而提高標簽的靈活性和復用性。
要想讓一個自定義標簽具有屬性,通常需要完成兩個任務:
- 在標簽處理器中編寫每個屬性對應的setter方法
- 在TLD文件中描術標簽的屬性
為自定義標簽定義屬性時,每個屬性都必須按照JavaBean的屬性命名方式,在標簽處理器中定義屬性名對應的setter方法,用來接收 JSP頁面調用自定義標簽時傳遞進來的屬性值。 例如屬性url,在標簽處理器類中就要定義相應的setUrl(String url)方法。
在標簽處理器中定義相應的set方法后,JSP引擎在解析執行開始標簽前,也就是調用doStartTag方法前,會調用set屬性方法,為標簽設置屬性。
2.1、開發帶屬性的標簽范例
范例1:通過標簽的屬性控制標簽體的執行次數
示例代碼如下:
SimpleTagDemo5.java
1 package me.gacl.web.simpletag; 2 3 import java.io.IOException; 4 import javax.servlet.jsp.JspException; 5 import javax.servlet.jsp.tagext.SimpleTagSupport; 6 7 /** 8 * @author gacl 9 * SimpleTagSupport類實現了SimpleTag接口, 10 * SampleTagDemo5類繼承SimpleTagSupport 11 * 通過標簽的屬性控制標簽體的執行次數 12 */ 13 public class SimpleTagDemo5 extends SimpleTagSupport { 14 15 /** 16 * 定義標簽的屬性 17 */ 18 private int count; 19 20 /**count屬性對應的set方法 21 * @param count 22 */ 23 public void setCount(int count) { 24 this.count = count; 25 } 26 27 /* 簡單標簽使用這個方法就可以完成所有的業務邏輯 28 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 29 * 重寫doTag方法,通過標簽的屬性控制標簽體的執行次數 30 */ 31 @Override 32 public void doTag() throws JspException, IOException { 33 for (int i = 0; i < count; i++) { 34 this.getJspBody().invoke(null); 35 } 36 } 37 38 }
在WEB-INF目錄下的tld文件中添加對該標簽的描述,如下所示:
1 <tag> 2 <!-- 標簽名 --> 3 <name>demo5</name> 4 <!-- 標簽處理器類--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo5</tag-class> 6 <!-- 標簽體允許的內容--> 7 <body-content>scriptless</body-content> 8 9 <!-- 標簽的屬性描述 --> 10 <attribute> 11 <description>描述標簽的count屬性</description> 12 <!-- 標簽的count屬性 --> 13 <name>count</name> 14 <required>true</required> 15 <!-- rtexprvalue用來指示標簽的屬性值是否可以是一個表達式, 16 一般設置為true,true就表示允許標簽的屬性值可以是一個表達式--> 17 <rtexprvalue>true</rtexprvalue> 18 </attribute> 19 </tag>
在jsp頁面引入標簽庫並使用自定義標簽
1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中導入自定義標簽庫 --%> 3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%> 4 <%--在jsp頁面中也可以使用這種方式導入標簽庫,直接把uri設置成標簽庫的tld文件所在目錄 --%> 5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%> 6 <!DOCTYPE HTML> 7 <html> 8 <head> 9 <title>通過標簽的屬性控制標簽體的執行次數</title> 10 </head> 11 12 <body> 13 <%--在jsp頁面中使用自定義標簽,標簽有一個count屬性 --%> 14 <gacl:demo5 count="2"> 15 <h1>孤傲蒼狼</h1> 16 </gacl:demo5> 17 </body> 18 </html>
運行效果如下:
如果標簽的屬性值是8種基本數據類型,那么在JSP頁面在傳遞字符串時,JSP引擎會自動轉換成相應的類型,但如果標簽的屬性值是復合數據類型,那么JSP引擎是無法自動轉換的
范例2:標簽接收的屬性值是一個復合數據類型,該如何給標簽的屬性賦值
示例代碼如下:
SimpleTagDemo6.java
1 package me.gacl.web.simpletag; 2 3 import java.io.IOException; 4 import java.util.Date; 5 6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8 9 /** 10 * @author gacl 11 * SimpleTagSupport類實現了SimpleTag接口, 12 * SampleTagDemo6類繼承SimpleTagSupport 13 * 標簽的屬性說明 14 */ 15 public class SimpleTagDemo6 extends SimpleTagSupport { 16 17 /** 18 * 定義標簽的屬性 19 */ 20 private Date date; 21 22 /**date屬性對應的set方法 23 * @param date 24 */ 25 public void setDate(Date date) { 26 this.date = date; 27 } 28 29 /* 簡單標簽使用這個方法就可以完成所有的業務邏輯 30 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 31 * 重寫doTag方法,輸出date屬性值 32 */ 33 @Override 34 public void doTag() throws JspException, IOException { 35 this.getJspContext().getOut().write(date.toLocaleString()); 36 } 37 }
在WEB-INF目錄下的tld文件中添加對該標簽的描述,如下所示:
1 <tag> 2 <!-- 標簽名 --> 3 <name>demo6</name> 4 <!-- 標簽處理器類--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo6</tag-class> 6 <!-- 標簽體允許的內容--> 7 <body-content>empty</body-content> 8 9 <!-- 標簽的屬性描述 --> 10 <attribute> 11 <description>描述標簽的date屬性</description> 12 <!-- 標簽的date屬性,復合數據類型 --> 13 <name>date</name> 14 <required>true</required> 15 <!-- rtexprvalue用來指示標簽的屬性值是否可以是一個表達式, 16 一般設置為true,true就表示允許標簽的屬性值可以是一個表達式--> 17 <rtexprvalue>true</rtexprvalue> 18 </attribute> 19 </tag>
在jsp頁面引入標簽庫並使用自定義標簽
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中導入自定義標簽庫 --%> 3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%> 4 <%--在jsp頁面中也可以使用這種方式導入標簽庫,直接把uri設置成標簽庫的tld文件所在目錄 --%> 5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%> 6 <!DOCTYPE HTML> 7 <html> 8 <head> 9 <title>如果標簽接收的屬性值是一個復合數據類型,該如何給標簽的屬性賦值</title> 10 </head> 11 12 <body> 13 <%-- 14 在jsp頁面中使用自定義標簽,標簽有一個date屬性 ,是一個復合數據類型 15 如果標簽的屬性值是8種基本數據類型,那么在JSP頁面在傳遞字符串時,JSP引擎會自動轉換成相應的類型 16 但如果標簽的屬性值是復合數據類型,那么JSP引擎是無法自動轉換的, 17 這里將一個字符串賦值給demo6標簽的date屬性,在運行標簽時就會出現如下錯誤: 18 Unable to convert string "1988-05-07" to class "java.util.Date" for attribute "date": 19 Property Editor not registered with the PropertyEditorManager 20 <gacl:demo6 date="1988-05-07"> 21 </gacl:demo6> 22 --%> 23 <%--如果一定要給標簽的復合屬性賦值,那么可以采用表達式的方式給復合屬性賦值,如下所示: --%> 24 25 <% 26 Date d = new Date(); 27 request.setAttribute("date", d); 28 %> 29 30 <gacl:demo6 date="${date}"/> 31 <hr/> 32 <gacl:demo6 date="<%=new Date()%>"/> 33 </body> 34 </html>
運行效果如下:
2.1、tld文件中用於描述標簽屬性的<attribute>元素說明
<tag>元素的<attribute>子元素用於描述自定義標簽的一個屬性,自定義標簽所具有的每個屬性都要對應一個<attribute>元素
例如:
1 <tag> 2 <!-- 標簽名 --> 3 <name>demo5</name> 4 <!-- 標簽處理器類--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo5</tag-class> 6 <!-- 標簽體允許的內容--> 7 <body-content>scriptless</body-content> 8 9 <!-- 標簽的屬性描述 --> 10 <attribute> 11 <description>描述標簽的count屬性</description> 12 <!-- 標簽的count屬性 --> 13 <name>count</name> 14 <required>true</required> 15 <!-- rtexprvalue用來指示標簽的屬性值是否可以是一個表達式, 16 一般設置為true,true就表示允許標簽的屬性值可以是一個表達式--> 17 <rtexprvalue>true</rtexprvalue> 18 </attribute> 19 </tag>
<attribute>元素的子元素說明:
到此,簡單標簽的開發技術就算是全部講完了,在下一篇博文中會編寫一些自定義標簽的案例來加深自定標簽技術的學習和理解。