一、自定义标签开发库简介:
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目录下
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 }
标签声明:
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:
标签声明:
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:
标签实现类:
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 for(int i=0;i<5;i++){ 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>/simpletag</uri> 12 13 14 <tag> 15 <name>demo1</name> 16 <tag-class>com.web.simpletag.SimpleTagDemo1</tag-class> 17 <body-content>scriptless</body-content><!-- jsp2.0之后不运行标签体里面写脚本代码,所以用scriptless --> 18 </tag> 19 20 </taglib>
使用标签:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@taglib uri="/simpletag" prefix="simple" %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>My JSP ‘1.jsp‘ starting page</title> 7 </head> 8 9 <body> 10 <simple:demo1>hahaha <br/></simple:demo1> 11 </body> 12 </html>
原文地址:https://www.cnblogs.com/niuchuangfeng/p/9123927.html