一、自定義標簽開發庫簡介: Tag介面的方法: 二、自定義標簽入門:輸出客戶機ip 1.編寫一個實現tag介面的java類 ViewIPTag.java 2.在tld文件中對標簽處理器類進行描述(tld文件的位置:WEB-INF下,可以抄apache-tomcat/webapps\examples\ ...
一、自定義標簽開發庫簡介
Tag介面的方法:
二、自定義標簽入門:輸出客戶機ip
1.編寫一個實現tag介面的java類
-
ViewIPTag.java
1 package com.web.tag;
2
3 import java.io.IOException;
4
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.jsp.JspException;
7 import javax.servlet.jsp.JspWriter;
8 import javax.servlet.jsp.tagext.TagSupport;
9
10 //Tag介面實現類
11 public class ViewIPTag extends TagSupport{
12 @Override
13 public int doStartTag() throws JspException {
14
15 HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();
16 JspWriter out = this.pageContext.getOut();
17
18
19 String ip = request.getRemoteAddr();
20 try {
21 out.print(ip);
22 } catch (IOException e) {
23 throw new RuntimeException(e);
24 }
25
26 return super.doStartTag();
27 }
28 }
2.在tld文件中對標簽處理器類進行描述(tld文件的位置:WEB-INF下,可以抄apache-tomcat/webapps\examples\WEB-INF\jsp2\jsp2-example-taglib.tld)com.tld:這個文件放在WEB-INF目錄下
-
tld文件:
1 <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
4 version="2.0">
5
6 <description>A tag library exercising SimpleTag handlers.</description>
7 <tlib-version>1.0</tlib-version>
8 <short-name>com</short-name>
9 <uri>http://www.sina.cn</uri><!-- 綁定url -->
10
11
12 <tag>
13 <name>viewIP</name><!-- 標簽的名稱 -->
14 <tag-class>com.web.tag.ViewIPTag</tag-class><!-- 標簽實現類的完整類名 -->
15 <body-content>empty</body-content><!-- 標簽體為空 -->
16 </tag>
17
18 </taglib>
3.在jsp頁面中導入和使用自定義標簽
-
1.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@taglib uri="http://www.sina.cn" prefix="com" %> <!-- 導入標簽 -->
3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
7 <title>Insert title here</title>
8 </head>
9 <body>
10 您的ip:<com:viewIP/><!-- 使用標簽 -->
11 </body>
12 </html>
三、Tag介面的執行流程
自定義標簽調用圖:
jsp翻譯成servlet部分源代碼:
1 out.write(" 您的ip是:");
2 if (_jspx_meth_com_005fviewIP_005f0(_jspx_page_context))
3 return;
4 out.write("\r\n");
5 out.write(" </body>\r\n");
6 out.write("</html>\r\n");
7 } catch (java.lang.Throwable t) {
8 if (!(t instanceof javax.servlet.jsp.SkipPageException)){
9 out = _jspx_out;
10 if (out != null && out.getBufferSize() != 0)
11 try {
12 if (response.isCommitted()) {
13 out.flush();
14 } else {
15 out.clearBuffer();
16 }
17 } catch (java.io.IOException e) {}
18 if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
19 else throw new ServletException(t);
20 }
21 } finally {
22 _jspxFactory.releasePageContext(_jspx_page_context);
23 }
24 }
25
26 private boolean _jspx_meth_com_005fviewIP_005f0(javax.servlet.jsp.PageContext _jspx_page_context)
27 throws java.lang.Throwable {
28 javax.servlet.jsp.PageContext pageContext = _jspx_page_context;
29 javax.servlet.jsp.JspWriter out = _jspx_page_context.getOut();
30 // com:viewIP
31 com.web.tag.ViewIPTag _jspx_th_com_005fviewIP_005f0 = (com.web.tag.ViewIPTag) _005fjspx_005ftagPool_005fcom_005fviewIP_005fnobody.get(com.web.tag.ViewIPTag.class);
32 boolean _jspx_th_com_005fviewIP_005f0_reused = false;
33 try {
34 _jspx_th_com_005fviewIP_005f0.setPageContext(_jspx_page_context);//調用setPageContext()方法
35 _jspx_th_com_005fviewIP_005f0.setParent(null); 36 int _jspx_eval_com_005fviewIP_005f0 = _jspx_th_com_005fviewIP_005f0.doStartTag(); 37 if (_jspx_th_com_005fviewIP_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) { 38 return true; 39 } 40 _005fjspx_005ftagPool_005fcom_005fviewIP_005fnobody.reuse(_jspx_th_com_005fviewIP_005f0); 41 _jspx_th_com_005fviewIP_005f0_reused = true; 42 } finally { 43 org.apache.jasper.runtime.JspRuntimeLibrary.releaseTag(_jspx_th_com_005fviewIP_005f0, _jsp_getInstanceManager(), _jspx_th_com_005fviewIP_005f0_reused); 44 } 45 return false; 46 }
四、 傳統標簽開發技術
開發人員在編寫Jsp頁面時,經常還需要在頁面中引入一些邏輯:
1、控制jsp頁面某一部分內容是否執行
API:
-
標簽實現類:TagDemo1.java
1 package com.web.tag;
2
3 import javax.servlet.jsp.JspException;
4 import javax.servlet.jsp.tagext.TagSupport;
5
6 public class TagDemo1 extends TagSupport{
7
8 @Override
9 public int doStartTag() throws JspException {
10
11 //實際開發場景————如果有許可權則輸出,沒有許可權則不輸出
12 return TagSupport.EVAL_BODY_INCLUDE;
13 }
14
15 }
-
標簽聲明:tld文件
1 <tag>
2 <name>demo1</name>
3 <tag-class>com.web.tag.TagDemo1</tag-class>
4 <body-content>JSP</body-content><!--標簽體的內容 empty JSP scriptless tagdepentend-->
5 </tag>
6
tld文件類型中的四種標簽體:EMPTY JSP scriptless tagdepentend
-
使用標簽:jsp頁面
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@taglib uri="http://www.sina.cn" prefix="com" %>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6 <title>使用自定義標簽控制jsp部分內容是否輸出(標簽體)</title>
7 </head>
8 <com:demo1>hahaha</com:demo1>
9 <body>
10
11 </body>
12 </html>
2、控制整個jsp頁面內容是否執行
API:
-
標簽實現類:TagDemo2.java:
-
標簽聲明:tld文件
1 <tag>
2 <name>demo2</name>
3 <tag-class>com.web.tag.TagDemo2</tag-class>
4 <body-content>empty</body-content><!--標簽體為空-->
5 </tag>
6
-
使用標簽:
3、控制標簽體重覆輸出
API:
-
標簽實現類:TagDemo3
1 package com.web.tag;
2
3 import javax.servlet.jsp.JspException;
4 import javax.servlet.jsp.tagext.IterationTag;
5 import javax.servlet.jsp.tagext.Tag;
6 import javax.servlet.jsp.tagext.TagSupport;
7 //控制標簽體輸出5次
8 public class TagDemo3 extends TagSupport{
9 //次數
10 int x = 5;
11 @Override
12 public int doStartTag() throws JspException {
13 return Tag.EVAL_BODY_INCLUDE;
14 }
15
16 @Override
17 //在標簽體執行完之後、結束標簽之前調用
18 public int doAfterBody() throws JspException {
19 x--;
20 if(x>0){
21 return IterationTag.EVAL_BODY_AGAIN;
22 }else {
23 return IterationTag.SKIP_PAGE;
24 }
25 }
26 }
-
標簽聲明:
1 <tag>
2 <name>demo3</name>
3 <tag-class>com.web.tag.TagDemo3</tag-class>
4 <body-content>JSP</body-content>
5 </tag>
-
使用標簽:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@taglib uri="http://www.sina.cn" prefix="com" %>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6 <title>使用自定義標簽控制jsp部分內容是否輸出(標簽體)</title>
7 </head>
8 <body>
9 <com:demo3>控制標簽體重覆輸出 <br/></com:demo3>
10 </body>
11 </html>
4、改變標簽體內容輸出
API:
-
標簽實現類:TagDemo4.java:
1 package com.web.tag;
2
3 import java.io.IOException;
4
5 import javax.servlet.jsp.JspException;
6 import javax.servlet.jsp.tagext.BodyContent;
7 import javax.servlet.jsp.tagext.BodyTag;
8 import javax.servlet.jsp.tagext.BodyTagSupport;
9 import javax.servlet.jsp.tagext.Tag;
10
11 //修改標簽體內容輸出
12 public class TagDemo4 extends BodyTagSupport{
13
14 @Override
15 public int doStartTag() throws JspException {
16 return BodyTag.EVAL_BODY_BUFFERED;//返回這個參數,伺服器會把標簽體封裝成對象作為參數調用setBodyContent(BodyContent b)方法
17 }
18 @Override
19 public int doEndTag() throws JspException {
20 //得到標簽體
21 BodyContent bc = this.getBodyContent();
22 //得到內容
23 String content = bc.getString();
24 //轉成大寫
25 content = content.toUpperCase();
26
27 try {
28 this.pageContext.getOut().write(content);
29 } catch (IOException e) {
30 throw new RuntimeException(e);
31 }
32
33 return Tag.EVAL_PAGE;//繼續輸出jsp頁面其他內容
34 }
35 }
當在doStartTag()方法中返回BodyTag.EVAL_BODY_BUFFERED參數時,伺服器會把標簽體內容封裝成對象作為參數調用setBodyContent(BodyContent b)方法,然後在doEngTag()
中調用getBodyContent()方法返回BodyContent對象,從而得到標簽體內容進行修改輸出。
-
標簽聲明:
1 <tag>
2 <name>demo4</name>
3 <tag-class>com.web.tag.TagDemo4</tag-class>
4 <body-content>JSP</body-content>
5 </tag>
6
-
使用標簽:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@taglib uri="http://www.sina.cn" prefix="com" %>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6 <title>使用自定義標簽控制jsp部分內容是否輸出(標簽體)</title>
7 </head>
8 <com:demo4>aaaaaa</com:demo4>
9 <body>
10
11 </body>
12 </html>
5、Tag介面的體系:
五、簡單標簽開發技術
由於傳統標簽使用三個標簽介面來完成不同的功能,顯得過於繁瑣,不利於標簽技術的推廣, SUN公司為降低標簽技術的學習難度,在JSP 2.0中定義了一個更為簡單、便於編寫和調用的SimpleTag介面來實現標簽的功能。實現SimpleTag介面的標簽通常稱為簡單標簽。簡單標簽共定義了5個方法:
- setJspContext方法
- setParent和getParent方法
- setJspBody方法
- doTag方法
API:
實現類:
1、控制標簽體是否執行
-
標簽實現類:SimpleTagDemo1.java:
1 import javax.servlet.jsp.JspException;
2 import javax.servlet.jsp.tagext.JspFragment;
3 import javax.servlet.jsp.tagext.SimpleTagSupport;
4 //控制標簽體是否執行
5 public class SimpleTagDemo1 extends SimpleTagSupport{
6
7 @Override
8 public void doTag() throws JspException, IOException {
9 //獲取標簽體對象
10 JspFragment jf = this.getJspBody();
11 12
13 jf.invoke(this.getJspContext().getOut());//null也可以預設輸出給瀏覽器
14 15
16 }
17 }
-
標簽聲明:
1 <?xml version="1.0" encoding="UTF-8" ?>
2
3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
6 version="2.0">
7
8 <description>A tag library exercising SimpleTag handlers.</description>
9 <tlib-version>1.0</tlib-version>
10 <short-name>simple</short-name>
11 <uri