一、 自定義標(biāo)簽簡介
自定義標(biāo)簽主要用于移除jsp頁面中的java代碼。工程(tag)
使用自定義標(biāo)簽移除jsp頁面中的java代碼,只需要完成以下兩個步驟:
1.編寫一個實現(xiàn)tag接口的java類(標(biāo)簽處理類)。
2.編寫標(biāo)簽庫描述符(tld)文件,在tld文件中對標(biāo)簽處理器類進(jìn)行描述。
二、快速入門:使用標(biāo)簽輸出客戶機IP
這里我們先編寫一個tld文件(itcast.tld):
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-jsptaglibrary_2_1.xsd">
<tlib-version>1.0</tlib-version>
<short-name>itcast</short-name><!-- tld文件名字 -->
<uri>/itcast</uri><!-- 因為文件是放在WEB-INF下面 -->
<tag>
<name>viewIP</name><!-- 給標(biāo)簽起名 -->
<tag-class>cn.itcast.web.tag.ViewIPTag</tag-class><!-- 類的完整類名 -->
<body-content>empty</body-content><!-- 這里是操作標(biāo)簽體,如果不用,則使用empty -->
</tag>
</taglib>
注意:標(biāo)簽<body-content>為empty表示標(biāo)簽起始和結(jié)束之間沒有內(nèi)容。如<a ..../>,而不能是<a>...</a>。
說明:我們可以在MyEclipse中直接新建tld文件,然后填入相應(yīng)的信息:

其中Name是文件名,Version我們選擇最高版本,Shortname一般填入文件名,由于文件放在WEB-INF 下面,所以uri地址是/itcast。
實現(xiàn)類(ViewIPTag.java)
package cn.itcast.web.tag;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
//自定義標(biāo)簽類,注意繼承Tag接口
public class ViewIPTag implements Tag {
private PageContext pageContext;//用于保存頁面對象
@Override
public int doStartTag() throws JspException {
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
//得到out隱式對象,用于輸出
JspWriter out = pageContext.getOut();
//得到服務(wù)器地址
String ip = request.getRemoteAddr();
try {
out.write(ip);
} catch (IOException e) {
//這里子類不能拋出比父類還多的異常
throw new RuntimeException(e);
}
return 0;
}
@Override
public void setPageContext(PageContext arg0) {
this.pageContext = arg0;
}
@Override
public int doEndTag() throws JspException {
return 0;
}
@Override
public Tag getParent() {
return null;
}
@Override
public void release() {}
@Override
public void setParent(Tag arg0) {}
}
使用(1.jsp)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/itcast" prefix="itcast"%><!-- 和之前使用EL標(biāo)簽一樣,需要導(dǎo)入 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>客戶機IP</title>
</head>
<body>
您的IP是:<itcast:viewIP/>
<%
/* 等同于 */
String ip = request.getRemoteAddr();
out.write(ip);
%>
</body>
</html>
三、標(biāo)簽的執(zhí)行過程
jsp引擎遇到自定義標(biāo)簽時,首先創(chuàng)建標(biāo)簽處理類的實例對象,然后按照jsp規(guī)范定義的通信規(guī)則依次調(diào)用它的方法。
1.jsp引擎實例化標(biāo)簽處理類之后,將調(diào)用setPageContext方法將jsp頁面的pageContext對象傳遞給標(biāo)簽處理器,標(biāo)簽處理器以后可以通過這個pageContext對象與jsp頁面進(jìn)行通信。
2.setPageContext方法執(zhí)行完后,web容器接著調(diào)用setParent方法將當(dāng)前標(biāo)簽的父標(biāo)簽傳遞給當(dāng)前標(biāo)簽處理器,如果當(dāng)前標(biāo)簽沒有父標(biāo)簽,則傳遞給setParent方法的參數(shù)值為null。
3.調(diào)用了setPageContext方法和setParent方法之后,web容器執(zhí)行到自定義標(biāo)簽的開始標(biāo)簽時,就會調(diào)用標(biāo)簽處理器的doStartTag方法。
4.web容器執(zhí)行完自定義標(biāo)簽的標(biāo)簽體之后,就會接著去執(zhí)行自定義標(biāo)簽的結(jié)束標(biāo)簽,此時,web容器就會調(diào)用doEndTag方法。
5.通常web容器執(zhí)行完自定義標(biāo)簽后,標(biāo)簽處理器會駐留在內(nèi)存中,為其它請求服務(wù),直至停止web應(yīng)用時,web容器才會調(diào)用release方法。
自定義標(biāo)簽功能擴(kuò)展
開發(fā)人員在編寫jsp頁面時,經(jīng)常還需要在頁面中引入一些邏輯。例如:
(1)控制jsp頁面某一部分內(nèi)容是否執(zhí)行
(2)控制整個jsp頁面是否執(zhí)行
(3)控制jsp頁面內(nèi)容重復(fù)執(zhí)行
(4)修改jsp頁面內(nèi)容輸出
自定義標(biāo)簽除了可以移除jsp頁面的java代碼,也可以實現(xiàn)以上功能。
例:控制jsp頁面某一部分內(nèi)容是否執(zhí)行
TagDemo1.java
package cn.itcast.web.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;;
public class TagDemo1 extends TagSupport {
@Override
public int doStartTag() throws JspException {
//return Tag.EVAL_BODY_INCLUDE;//返回此常量則會執(zhí)行標(biāo)簽體
return Tag.SKIP_BODY;//如果要跳過標(biāo)簽體,則使用此常量
}
}
itcast.tld中
<tag>
<name>demo1</name>
<tag-class>cn.itcast.web.tag.TagDemo1</tag-class>
<body-content>JSP</body-content>
</tag>
注意:此處<body-content>為JSP,必須是大寫,表示標(biāo)簽之間有內(nèi)容。內(nèi)容接受所遇jsp語法,當(dāng)然這里我們只是表示標(biāo)簽之間有內(nèi)容,而內(nèi)容執(zhí)行不執(zhí)行依據(jù)所定義的類。當(dāng)然還可以是tagdependent和scriptless,但用的不多,此處不再詳述。
注意:此處我們繼承的是TagSupport類,因為每次繼承Tag接口需要實現(xiàn)很多用不到的方法,于是這里我們繼承此默認(rèn)實現(xiàn)類可以簡便一些。關(guān)于Tag接口的繼承關(guān)系如下圖:
使用(2.jsp)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/itcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>控制jsp頁面某一部分內(nèi)容是否執(zhí)行</title>
</head>
<body>
<itcast:demo1>
xxx
</itcast:demo1>
</body>
</html>
使用這個標(biāo)簽就表示xxx不會被執(zhí)行。當(dāng)然具體怎樣控制我們可以在類中進(jìn)行細(xì)化。
例:控制整個jsp頁面是否執(zhí)行
itcast.tld
<tag>
<name>demo2</name>
<tag-class>cn.itcast.web.tag.TagDemo2</tag-class>
<body-content>empty</body-content>
</tag>
TagDemo2.java
package cn.itcast.web.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo2 extends TagSupport {
@Override
public int doEndTag() throws JspException {
return Tag.SKIP_PAGE;//此常量表示結(jié)束標(biāo)簽后買年余下的jsp頁面不會執(zhí)行
//return Tag.EVAL_PAGE;//此常量表示會執(zhí)行
}
}
3.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/itcast" prefix="itcast"%>
<itcast:demo2/><!-- 即控制結(jié)束標(biāo)簽后面的jsp內(nèi)容是否執(zhí)行 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>控制整個jsp頁面是否執(zhí)行</title>
</head>
<body>
</body>
</html>
例:控制jsp頁面內(nèi)容重復(fù)執(zhí)行
itcast.tld
<tag>
<name>demo3</name>
<tag-class>cn.itcast.web.tag.TagDemo3</tag-class>
<body-content>JSP</body-content>
</tag>
TagDemo3
package cn.itcast.web.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.IterationTag;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo3 extends TagSupport {
int x = 5;
@Override
public int doAfterBody() throws JspException {
x--;
//注意:控制標(biāo)簽體重復(fù)執(zhí)行的時候需要的常量需要的不是Tag常量,而是IterationTag常量
if(x > 0){
return IterationTag.EVAL_BODY_AGAIN;
}else{
return IterationTag.SKIP_BODY;
}
}
@Override
public int doStartTag() throws JspException {
//注意:要想重復(fù)執(zhí)行,則首先要讓標(biāo)簽體執(zhí)行才行
return Tag.EVAL_BODY_INCLUDE;
}
}
itcast.tld
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/itcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>控制頁面重復(fù)執(zhí)行</title>
</head>
<body>
<itcast:demo3>
這里的頁面內(nèi)容將重復(fù)執(zhí)行
</itcast:demo3>
</body>
</html>
例:修改jsp頁面內(nèi)容輸出
itcast.tld
<tag>
<name>demo4</name>
<tag-class>cn.itcast.web.tag.TagDemo4</tag-class>
<body-content>JSP</body-content>
</tag>
TagDemo4
package cn.itcast.web.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class TagDemo4 extends BodyTagSupport {
@Override
public int doEndTag() throws JspException {
//得到標(biāo)簽體內(nèi)容字符串
String content = this.getBodyContent().getString();
//將標(biāo)簽體內(nèi)容改為大寫
String result = content.toUpperCase();
//得到out輸入對象
try {
this.pageContext.getOut().write(result);
} catch (IOException e) {
throw new RuntimeException(e);
}
return Tag.EVAL_PAGE;//表示標(biāo)簽體余下的內(nèi)容還要輸出
}
@Override
public int doStartTag() throws JspException {
//要想修改標(biāo)簽體,則下面必須返回此常量
return BodyTag.EVAL_BODY_BUFFERED;
}
}
5.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/itcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>修改標(biāo)簽體內(nèi)容</title>
</head>
<body>
<itcast:demo4>
aaa
</itcast:demo4>
</body>
</html>
得到的輸出結(jié)果是AAA。
最后,其實上面是一種很傳統(tǒng)的方式,使用起來并不方便,一般我們很少使用。
四、簡單標(biāo)簽
由于傳統(tǒng)標(biāo)簽使用三個標(biāo)簽接口來完成不同的功能,顯得過于繁瑣,不利于標(biāo)簽技術(shù)的推廣,sun公司為降低標(biāo)簽技術(shù)的學(xué)習(xí)難度,在jsp2.0中定義了一個更為簡單、便于編寫和調(diào)用的SimpleTag接口來實現(xiàn)標(biāo)簽的功能。實現(xiàn)SimpleTag接口的標(biāo)簽通常稱為簡單標(biāo)簽。簡單標(biāo)簽定義了5個方法:
-
setJspContext方法:用于把jsp頁面的pageContext對象傳遞給標(biāo)簽處理器對象; -
setParent和getParent方法:前者用于把父標(biāo)簽處理器對象傳遞給當(dāng)前處理器對象。后者用于獲得當(dāng)前標(biāo)簽的父標(biāo)簽處理器對象。 -
setJspBody:用于把代表標(biāo)簽體的JspFragment對象傳遞給標(biāo)簽處理器對象。 -
doTag方法:用于完成所有的標(biāo)簽邏輯,包括輸出、迭代、修改標(biāo)簽體內(nèi)容等。在doTag方法中可以拋出javax.servlet.jsp.SkipPageException異常,用于通知web容器不再執(zhí)行jsp頁面中位于結(jié)束標(biāo)記后面的內(nèi)容,這等效于在傳統(tǒng)標(biāo)簽的doEndTag方法中返回Tag.SKIP_PAGE的情況。
1.SimpleTag接口方法的執(zhí)行順序
(1)當(dāng)web容器準(zhǔn)備開始執(zhí)行標(biāo)簽時,會調(diào)用如下方法完成標(biāo)簽的初始化:
- 1.web容器調(diào)用標(biāo)簽處理器對象的
setJspContext方法,將代表jsp頁面的pageContext對象傳遞給標(biāo)簽處理器對象。 - 2.web容器調(diào)用標(biāo)簽處理器對象的
setParent方法,將父標(biāo)簽處理器對象傳遞給這個標(biāo)簽處理器對象。注意:只有在標(biāo)簽存在父標(biāo)簽的情況下,web容器才會調(diào)用此方法。 - 3.如果調(diào)用標(biāo)簽時設(shè)置了屬性,容器將調(diào)用每個屬性對應(yīng)的setter方法把屬性值傳遞給標(biāo)簽處理器對象。如果標(biāo)簽的屬性值是EL表達(dá)式或腳本表達(dá)式,則web容器首先計算表達(dá)式的值,然后把值傳遞給標(biāo)簽處理器對象。
- 4.如果簡單標(biāo)簽有標(biāo)簽體,容器將調(diào)用
setJspBody方法把代表標(biāo)簽體的JspFragment對象傳遞進(jìn)來。
(2)執(zhí)行標(biāo)簽時:
容器調(diào)用標(biāo)簽處理器的doTag方法,開發(fā)人員在方法體內(nèi)通過操作JspFragment對象,就可以實現(xiàn)是否執(zhí)行、迭代、修改標(biāo)簽體的目的。當(dāng)然是先得到此對象。
2.JspFragment類
javax.servlet.jsp.tagext.JspFragment類是jsp2.0中定義的,它的實例對象代表jsp頁面中的一段符合jsp語法規(guī)范的jsp片段,這段jsp片段中不能包含jsp腳本元素。web容器在處理簡單標(biāo)簽的標(biāo)簽體時,會把標(biāo)簽體內(nèi)容用一個
JspFragment對象表示,并調(diào)用標(biāo)簽處理對象的setJspBody方法把JspFragment對象傳遞給標(biāo)簽處理器對象。JspFragment類中定義了兩個方法,如下所示:
getJspContext方法:用于返回代表調(diào)用頁面的JspContext對象。
invoke方法:用于執(zhí)行JspFragment對象所代表的jsp代碼片段;參數(shù)out用于指定將JspFragment對象的執(zhí)行結(jié)果寫入到哪個輸出流對象中,如果傳遞給參數(shù)out值為null,則將執(zhí)行結(jié)果寫入到JspContext.getOut方法返回的輸出流對象中。(即寫給瀏覽器)。
3.invoke方法詳解
JspFragment.invoke方法是JspFragment最重要的方法,利用這個方法可以控制是否執(zhí)行和輸出標(biāo)簽體的內(nèi)容、是否迭代執(zhí)行標(biāo)簽體的內(nèi)容或?qū)?biāo)簽體的執(zhí)行結(jié)果進(jìn)行修改后再輸出。例如:
- 1.在標(biāo)簽處理器中如果沒有調(diào)用
JspFragment.invoke方法,其結(jié)果就相當(dāng)于忽略標(biāo)簽體的內(nèi)容; - 2.在標(biāo)簽處理器中重復(fù)調(diào)用
JspFragment.invoke方法,則標(biāo)簽體內(nèi)容將會別重復(fù)執(zhí)行; - 3.若想在標(biāo)簽處理器中修改標(biāo)簽體內(nèi)容,只需在調(diào)用
invoke方法時指定一個可取出結(jié)果數(shù)據(jù)的輸出流對象(StringWriter),讓標(biāo)簽體的執(zhí)行結(jié)果輸出到該輸出流對象中,然后從該輸出流對象中取出數(shù)據(jù)進(jìn)行修改后再輸出到目標(biāo)設(shè)備,即可達(dá)到修改標(biāo)簽體的目的。
4.使用簡單標(biāo)簽實現(xiàn)之前傳統(tǒng)標(biāo)簽完成的例子
例:使用簡單標(biāo)簽實現(xiàn)控制標(biāo)簽體是否執(zhí)行
WebRoot/WEB-INF/simpletag.tld
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-jsptaglibrary_2_1.xsd">
<tlib-version>1.0</tlib-version>
<short-name>simpleitcast</short-name>
<uri>/simpleitcast</uri>
<tag>
<name>demo1</name>
<tag-class>cn.itcast.web.simpletag.SimpleTagDemo1</tag-class>
<!-- 這里注意:在簡單標(biāo)簽中不允許使用JSP,因為新版的標(biāo)簽技術(shù)不允許在標(biāo)簽體中使用
腳本代碼,比如<%%>這樣的,scriptless表示無腳本 -->
<body-content>scriptless</body-content>
</tag>
</taglib>
SimpleTagDemo1
package cn.itcast.web.simpletag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//使用簡單標(biāo)簽控制標(biāo)簽體是否執(zhí)行
public class SimpleTagDemo1 extends SimpleTagSupport {
//簡單標(biāo)簽使用此方法完成所有的業(yè)務(wù)邏輯
@Override
public void doTag() throws JspException, IOException {
//得到JspFragment對象,即得到一段jsp片段
JspFragment jf = this.getJspBody();
//得到pageContext對象
PageContext pageContext = (PageContext) this.getJspContext();
jf.invoke(pageContext.getOut());
//jf.invoke(null);//此行代碼表示默認(rèn)執(zhí)行上面兩行代碼,表示默認(rèn)傳遞給瀏覽器
}
}
WebRoot/simpletag/1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/simpleitcast" prefix="itcast"%><!-- 這里我們前綴還是使用itcast -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>使用簡單標(biāo)簽實現(xiàn)控制標(biāo)簽體是否執(zhí)行</title>
</head>
<body>
<itcast:demo1>
xxxx
</itcast:demo1>
</body>
</html>
這里我們是允許標(biāo)簽體中的內(nèi)容進(jìn)行輸出執(zhí)行。輸出xxxx。當(dāng)然如果我們不想讓標(biāo)簽體執(zhí)行,那就不寫
PageContext pageContext = (PageContext) this.getJspContext();
jf.invoke(pageContext.getOut());
或不寫jf.invoke(null);。
例:控制標(biāo)簽體重復(fù)執(zhí)行
simpletag.tld
<tag>
<name>demo2</name>
<tag-class>cn.itcast.web.simpletag.SimpleTagDemo2</tag-class>
<body-content>scriptless</body-content>
</tag>
SimpleTagDemo2
package cn.itcast.web.simpletag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//控制標(biāo)簽體重復(fù)執(zhí)行多次
public class SimpleTagDemo2 extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody();
for(int i = 0; i < 10; i++){
jf.invoke(null);
}
}
}
2.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/simpleitcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>控制標(biāo)簽體重復(fù)執(zhí)行多次</title>
</head>
<body>
<itcast:demo2>
xxxx
</itcast:demo2>
</body>
</html>
例:修改標(biāo)簽體中的內(nèi)容
simpletag.tld
<tag>
<name>demo3</name>
<tag-class>cn.itcast.web.simpletag.SimpleTagDemo3</tag-class>
<body-content>scriptless</body-content>
</tag>
SimpleTagDemo3
package cn.itcast.web.simpletag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//修改標(biāo)簽體中的內(nèi)容
public class SimpleTagDemo3 extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody();
StringWriter sw = new StringWriter();//得到一個輸出流
jf.invoke(sw);//注意:要想修改標(biāo)簽體內(nèi)容個必須先執(zhí)行標(biāo)簽體
//得到標(biāo)簽體內(nèi)容
String content = sw.getBuffer().toString();
content = content.toUpperCase();//將標(biāo)簽體中的字符串變?yōu)榇髮?
PageContext pageContext = (PageContext) this.getJspContext();
pageContext.getOut().write(content);//輸出
}
}
3.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/simpleitcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>使用簡單標(biāo)簽修改標(biāo)簽體內(nèi)容</title>
</head>
<body>
<itcast:demo3>
aaa
</itcast:demo3>
</body>
</html>
說明:這里執(zhí)行是先讓標(biāo)簽體執(zhí)行,然后讓內(nèi)容輸出到我們自己定義的一個流中,然后我們從流中拿到數(shù)據(jù),修改之后再輸出給瀏覽器。
例:控制余下jsp頁面是否執(zhí)行
simpletag.tld
<tag>
<name>demo4</name>
<tag-class>cn.itcast.web.simpletag.SimpleTagDemo4</tag-class>
<body-content>scriptless</body-content>
</tag>
SimpleTagDemo4
package cn.itcast.web.simpletag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//控制標(biāo)簽體之后余下頁面是否執(zhí)行
public class SimpleTagDemo4 extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
//只要此方法拋出這個異常,那么余下的頁面將不會執(zhí)行
throw new SkipPageException();
}
}
4.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/simpleitcast" prefix="itcast"%>
<itcast:demo4/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>控制余下標(biāo)簽體不再執(zhí)行</title>
</head>
<body>
aaa
</body>
</html>
可以看到此功能很容易實現(xiàn)。
5.開發(fā)帶屬性的標(biāo)簽
- 要想讓一個自定義標(biāo)簽具有屬性,通常要完成兩個任務(wù):
在標(biāo)簽處理器中編寫每個屬性對應(yīng)的setter方法
在tld文件中描述標(biāo)簽的屬性 - 為自定義標(biāo)簽定義屬性時,每個屬性都必須按照javaBean的屬性命名方式,在標(biāo)簽處理器中定義屬性名對應(yīng)的setter方法,用來接收jsp頁面調(diào)用自定義標(biāo)簽時傳遞進(jìn)來的屬性值。例如,屬性url,在標(biāo)簽處理器類中就要定義相應(yīng)的setUrl(String url)方法。
- 在標(biāo)簽處理器中定義相應(yīng)的set方法后,jsp引擎在解析執(zhí)行開始標(biāo)簽前,也就是調(diào)用doStartTag方法前,會調(diào)用set屬性方法為標(biāo)簽設(shè)置屬性。
例:通過屬性控制標(biāo)簽體執(zhí)行的次數(shù)
simpletag.tld
<tag>
<name>demo5</name>
<tag-class>cn.itcast.web.simpletag.SimpleTagDemo5</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>count</name>
<required>true</required><!-- 這表示此屬性是必須的 -->
<!-- 此屬性是否是一個運行時表達(dá)式,若為false則只能是靜態(tài)的值,一般都是true -->
<rtexprvalue>true</rtexprvalue>
<type>java.lang.Integer</type><!-- 這個屬性是規(guī)定參數(shù)的java屬性,如果不正確則報錯 -->
</attribute>
</tag>
SimpleTagDemo5
package cn.itcast.web.simpletag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//通過屬性控制標(biāo)簽體的執(zhí)行
public class SimpleTagDemo5 extends SimpleTagSupport{
//這里注意:我們頂一個的是一個int類型的,但是標(biāo)簽中我們使用的是字符串類型,
//這里引擎幫我們進(jìn)行了轉(zhuǎn)換,但是只支持八種基本類型的轉(zhuǎn)換
private int count;
public void setCount(int count ){
this.count = count;
}
@Override
public void doTag() throws JspException, IOException {
for(int i = 0; i < count; i++){
this.getJspBody().invoke(null);
}
}
}
5.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/simpleitcast" prefix="itcast"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>通過屬性控制標(biāo)簽體執(zhí)行次數(shù)</title>
</head>
<body>
<!-- 如果在配置文件中rtexprvalue為true,則這里可以是一個表達(dá)式 -->
<itcast:demo5 count="5">
xxx
</itcast:demo5>
</body>
</html>
**注意:引擎只能轉(zhuǎn)換八種基本類型數(shù)據(jù),而不能轉(zhuǎn)換復(fù)雜類型數(shù)據(jù),如日期類型。但入股我們一定要傳入復(fù)雜類型的話一般有兩種方式:
<%
Data date = new Date();
request.setAttribute("date", date);
%>
<itcast:demo6 date="${date}">
xxx
</itcast:demo6>
或者:
<itcast:demo6 date="<%=date %>">
xxx
</itcast:demo6>
最后我們給出屬性配置中的一些標(biāo)簽:
