一. 自定義標籤的開發步驟
1、編寫一個類實現Tag接口。這個類就稱之爲標籤處理類
TagSupport實現了Tag接口。
public class ShowRemoteIpTag extendsTagSupport{
@Override
publicint doStartTag() throws JspException {
Stringip = pageContext.getRequest().getRemoteAddr();
JspWriterout = pageContext.getOut();
try {
out.write(ip);
}catch (IOException e) {
e.printStackTrace();
}
returnsuper.doStartTag();
}
}
2、在WEB-INF目錄下建立一個擴展名爲tld的xml文件。(Tomcat找)
<?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/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>itheima</short-name>
<uri>http://www.itheima.com/jsp/tag</uri>
<tag>
<description>Showremote ip</description>
<name>showRemoteIp</name>
<tag-class>com.itheima.tag.ShowRemoteIpTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3、在web.xml中對tld文件中的uri和tld文件的實際存儲位置進行對應配置(可選的)
<jsp-config>
<taglib>
<taglib-uri>http://www.itheima.com/jsp/tag</taglib-uri>
<taglib-location>/WEB-INF/itheima.tld</taglib-location>
</taglib>
</jsp-config>
4、 在JSP中通過taglib指令引入標籤庫
二. TLD標籤的主要元素
taglib:
short-name:引用的名稱空間
uri:唯一的uri地址,沒有實際意義。同xmlschema的uri一樣
tlib-version:版本號。新建的東東1.0
tag:描述一個標籤
name:標籤名
tag-class:標籤處理類。全類名
body-content:主體內容的類型
可選值:
empty:沒有主體內容。傳統和簡單標籤都可以用
JSP:有主體內容。傳統標籤使用(html,el,java腳本,java表達式。凡是jsp中可以出現的都可以作爲主體內容)
scriptless:有主體內容。簡單標籤使用。(html,el。與JSP不同的是,主體內容不能出現java腳本或表達式)
tagdepentend:是否將主體內容當做字符串處理。
attribute:描述標籤的一個屬性
name:屬性名稱
required:是否是必須的屬性.true|false
rtexprvalue:屬性取值是否支持表達式(EL或Java 表達式runtimeexpression value)
二. 傳統標籤: 標籤類的生命週期與Servlet一樣.
JspTag接口
Tag接口: 繼承於JspTag
EVAL_BODY_INCLDE:返回此屬性,會直接執行doAfterBody方法,不會去執行doinitBody方法和setBodyContent方法,設置在doStartTag方法.
EVAL_PAGE:會執行後面的內容.設置在doEndTag方法
SKIP_BODY:跳過主體內容,設置在doStratTag方法
SKIP_PAGE:跳過標籤後的頁面內容,在doEngTag方法
IterationTag接口:繼承於Tag
EVAL_BODY_AGAIN:重複執行doAfterBody方法.
BodyTag接口:繼承於IterationTag
EVAL_BODY_BUFFRED:在doStartTag方法上,返回此值,就會去執行doinitBody方法和setBodyContent方法,後面就可以拿到BodyContent對象.可以獲取主體的內容.然後再執行doAfterBody方法.
EVAL_BODY_TAG:無用,過時
TagSupport類:實現於IterationTag接口
BodyTagSupport類:實現於BodyTag接口,繼承於TagSupport類,如果需要拿到主體的內容,主繼承此類,此類可以拿到bodyContent對象,toString方法拿到此值.
執行過程:
二. 簡單標籤
SimpleTag接口:繼承於JspTag接口
SimpleTagSupport類:實現於SimpleTag接口
方法:
setJspContext方法:將JSP頁面的pageContext對象傳遞進來.由容器執行
setParent方法:把父標籤處理器對象傳遞給當前標籤處理器對象, 只有在標籤存在父標籤的情況下,WEB容器纔會調用這個方法。由容器執行
getParent方法:獲取當前標籤的父標籤處理器對象
doTag:用於處理所有的標籤邏輯.當拋出SkipPageException異常,則是告訴WEB容器不再執行JSP頁面位於結束標記後的內容.
JspFragment類:
方法:
getJspContext:得到JSP頁面的PageContext對象
publicabstract void invoke(java.io.Writer out):用於執行JspFragment對象所代表的JSP代碼片段. 參數out用於指定將JspFragment對象的執行結果寫入到哪個輸出流對象中,如果傳遞給參數out的值爲null,則將執行結果寫入到JspContext.getOut()方法返回的輸出流對象中。
JspFragment.invoke()方法:
在標籤處理器中如果沒有調用JspFragment.invoke方法,其結果就相當於忽略標籤體內容
在標籤處理器中重複調用JspFragment.invoke方法,則標籤體內容將會被重複執行
若想在標籤處理器中修改標籤體內容,只需在調用invoke方法時指定一個可取出結果數據的輸出流對象(例如StringWriter),讓標籤體的執行結果輸出到該輸出流對象中,然後從該輸出流對象中取出數據進行修改後再輸出到目標設備,即可達到修改標籤體的目的。
三. JSTL核心標籤庫
c:out:輸出指定內容,有默認值,可設置</>等符號是否轉義
c:set:可設置類對象屬性的值,也可以設置域對象屬性的值
c:remove:刪除指定域的指定屬性
c:catch:可處理異常
c:if:判斷
c:choose-c:when-c:otherwise:如if.else 這裏注意:when可以有多個,而otherwise只能有一個
c:foreach:迭代
c:url:重寫URL地址,如果帶/,會帶着應用名稱.如果客戶端cookie禁用,會帶着sessionid
c:param:可放在url,redired中.會跟着url後的參數
c:redirect:請求重定向,其中context重定向另一個應用,不過無用.
c:forTokens:如 1923-3/02 13:22:00 設置-/: 結果1923 3 02 13 22 00
StringTokenizer:此類如同c:forTokens一樣的功能