javawen学习自定义标签开发
来源:https://blog.csdn.net/tom0915/article/details/79037028
一、简单标签(SimpleTag)
由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。
实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:
- setJspContext方法
- setParent和getParent方法
- setJspBody方法
- doTag方法(非常重要),简单标签使用这个方法就可以完成所有的业务逻辑
二、SimpleTag方法介绍
2.1、setJspContext方法
用于把JSP页面的pageContext对象传递给标签处理器对象
2.2、setParent方法
用于把父标签处理器对象传递给当前标签处理器对象
2.3、getParent方法
用于获得当前标签的父标签处理器对象
2.4、setJspBody方法
用于把代表标签体的JspFragment对象传递给标签处理器对象
2.5、doTag方法
用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。
三、SimpleTag接口方法的执行顺序
当web容器开始执行标签时,会调用如下方法完成标签的初始化:
- WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
- WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
- 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
- 如果简单标签有标签体,WEB容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
- 执行标签时WEB容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。
四、开发简单标签实现页面逻辑
SUN公司针对SimpleTag接口提供了一个默认的实现类SimpleTagSupport,SimpleTagSupport类中实现了SimpleTag接口的所有方法,因此我们可以编写一个类继承SimpleTagSupport类,然后根据业务需要再重写doTag方法。
4.1、控制jsp页面某一部分内容是否执行
编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面不调用jspFrament.invoke方法即可。
示例代码如下:
SimpleTagDemo1.java
1 package me.gacl.web.simpletag;2 3 import java.io.IOException;4 5 import javax.servlet.jsp.JspException;6 import javax.servlet.jsp.PageContext;7 import javax.servlet.jsp.tagext.JspFragment;8 import javax.servlet.jsp.tagext.SimpleTagSupport;9 10 /** 11 * @author gacl 12 * SimpleTagSupport类实现了SimpleTag接口, 13 * SampleTagDemo1类继承SimpleTagSupport 14 */ 15 public class SimpleTagDemo1 extends SimpleTagSupport { 16 17 /* 简单标签使用这个方法就可以完成所有的业务逻辑 18 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 19 * 重写doTag方法,控制标签体是否执行 20 */ 21 @Override 22 public void doTag() throws JspException, IOException { 23 //得到代表jsp标签体的JspFragment 24 JspFragment jspFragment = this.getJspBody(); 25 26 //得到jsp页面的的PageContext对象 27 //PageContext pageContext = (PageContext) jspFragment.getJspContext(); 28 //调用JspWriter将标签体的内容输出到浏览器 29 //jspFragment.invoke(pageContext.getOut()); 30 31 //将标签体的内容输出到浏览器 32 jspFragment.invoke(null); 33 34 } 35 }
在WEB-INF目录下新建一个simpletag.tld文件,然后在simpletag.tld文件中添加对该标签处理类的描述,如下:
simpletag.tld文件代码如下:
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 <!-- description用来添加对taglib(标签库)的描述 -->8 <description>孤傲苍狼开发的SimpleTag自定义标签库</description>9 <!--taglib(标签库)的版本号 --> 10 <tlib-version>1.0</tlib-version> 11 <short-name>GaclSimpleTagLibrary</short-name> 12 <!-- 13 为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/simpletag , 14 在Jsp页面中引用标签库时,需要通过uri找到标签库 15 在Jsp页面中就要这样引入标签库:<%@taglib uri="/simpletag" prefix="gacl"%> 16 --> 17 <uri>/simpletag</uri> 18 19 <!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述 --> 20 <!-- 一个tag标记对应一个自定义标签 --> 21 <tag> 22 <description>SimpleTag(简单标签)Demo1</description> 23 <!-- 24 为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类的 25 通过demo1就能找到对应的me.gacl.web.simpletag.SimpleTagDemo1类 26 --> 27 <name>demo1</name> 28 <!-- 标签对应的处理器类--> 29 <tag-class>me.gacl.web.simpletag.SimpleTagDemo1</tag-class> 30 <!-- 31 tld文件中有四种标签体类型 :empty JSP scriptless tagdepentend 32 在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常 33 在传统标签中标签体body-content的值只允许是empty和JSP 34 如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的, 35 例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的 36 <gacl:sql>SELECT * FROM USER</gacl:sql> 37 在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可 38 --> 39 <body-content>scriptless</body-content> 40 </tag> 41 </taglib>
在jsp页面中导入并使用自定义标签,如下:
1 <%@ page language="java" pageEncoding="UTF-8"%>2 <%--在jsp页面中导入自定义标签库 --%>3 <%@taglib uri="/simpletag" prefix="gacl" %>4 <!DOCTYPE HTML>5 <html>6 <head>7 <title>用简单标签控制标签体是否执行</title>8 </head>9 10 <body> 11 12 <%--在jsp页面中使用自定义标签 demo1标签是带有标签体的,标签体的内容是"孤傲苍狼"这几个字符串--%> 13 <gacl:demo1> 14 孤傲苍狼 15 </gacl:demo1> 16 </body> 17 </html>
运行效果如下:
4.2、控制jsp页面内容重复执行
编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面重复调用jspFrament.invoke方法即可。
示例代码如下:
SimpleTagDemo2.java
1 package me.gacl.web.simpletag;2 3 import java.io.IOException;4 5 import javax.servlet.jsp.JspException;6 import javax.servlet.jsp.tagext.JspFragment;7 import javax.servlet.jsp.tagext.SimpleTagSupport;8 9 /** 10 * @author gacl 11 * SimpleTagSupport类实现了SimpleTag接口, 12 * SampleTagDemo2类继承SimpleTagSupport 13 */ 14 public class SimpleTagDemo2 extends SimpleTagSupport { 15 16 /* 简单标签使用这个方法就可以完成所有的业务逻辑 17 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 18 * 重写doTag方法,控制标签执行5次 19 */ 20 @Override 21 public void doTag() throws JspException, IOException { 22 // 得到代表jsp标签体的JspFragment 23 JspFragment jspFragment = this.getJspBody(); 24 for (int i = 0; i < 5; i++) { 25 // 将标签体的内容输出到浏览器 26 jspFragment.invoke(null); 27 } 28 } 29 }
在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:
1 <tag> 2 <!-- 标签名 --> 3 <name>demo2</name> 4 <!-- 标签处理器类--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class> 6 <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码--> 7 <body-content>scriptless</body-content> 8 </tag>
在jsp页面中导入并使用自定义标签,如下:
1 <%@ page language="java" pageEncoding="UTF-8"%>2 <%--在jsp页面中导入自定义标签库 --%>3 <%@taglib uri="/simpletag" prefix="gacl" %>4 <!DOCTYPE HTML>5 <html>6 <head>7 <title>用简单标签控制标签体执行5次</title>8 </head>9 10 <body> 11 12 <%--在jsp页面中使用自定义标签 --%> 13 <gacl:demo2> 14 孤傲苍狼<p/> 15 </gacl:demo2> 16 </body> 17 </html>
运行效果如下:
4.3、修改jsp页面内容输出
编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法调用jspFrament.invoke方法时,让执行结果写一个自定义的缓冲中即可,然后开发人员可以取出缓冲的数据修改输出。
示例代码如下:
SimpleTagDemo3.java
1 package me.gacl.web.simpletag;2 3 import java.io.IOException;4 import java.io.StringWriter;5 6 import javax.servlet.jsp.JspException;7 import javax.servlet.jsp.PageContext;8 import javax.servlet.jsp.tagext.JspFragment;9 import javax.servlet.jsp.tagext.SimpleTagSupport; 10 11 /** 12 * @author gacl 13 * SimpleTagSupport类实现了SimpleTag接口, 14 * SampleTagDemo3类继承SimpleTagSupport 15 */ 16 public class SimpleTagDemo3 extends SimpleTagSupport { 17 18 /* 简单标签使用这个方法就可以完成所有的业务逻辑 19 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 20 * 重写doTag方法,修改标签体里面的内容,将标签体的内容转换成大写 21 */ 22 @Override 23 public void doTag() throws JspException, IOException { 24 // 得到代表jsp标签体的JspFragment 25 JspFragment jspFragment = this.getJspBody(); 26 StringWriter sw = new StringWriter(); 27 //将标签体的内容写入到sw流中 28 jspFragment.invoke(sw); 29 //获取sw流缓冲区的内容 30 String content = sw.getBuffer().toString(); 31 content = content.toUpperCase(); 32 PageContext pageContext = (PageContext) this.getJspContext(); 33 //将修改后的content输出到浏览器中 34 pageContext.getOut().write(content); 35 } 36 }
在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:
1 <tag> 2 <!-- 标签名 --> 3 <name>demo3</name> 4 <!-- 标签处理器类--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo3</tag-class> 6 <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码--> 7 <body-content>scriptless</body-content> 8 </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>用简单标签修改jsp页面内容输出</title> 10 </head> 11 12 <body> 13 14 <%--在jsp页面中使用自定义标签 --%> 15 <gacl:demo3> 16 gacl_xdp 17 </gacl:demo3> 18 </body> 19 </html>
运行效果如下:
4.4、控制整个jsp页面是否执行
编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法抛出SkipPageException异常即可,jsp收到这个异常,将忽略标签余下jsp页面的执行。
示例代码如下:
SimpleTagDemo4.java
1 package me.gacl.web.simpletag;2 3 import java.io.IOException;4 import javax.servlet.jsp.JspException;5 import javax.servlet.jsp.SkipPageException;6 import javax.servlet.jsp.tagext.SimpleTagSupport;7 8 /**9 * @author gacl 10 * SimpleTagSupport类实现了SimpleTag接口, 11 * SampleTagDemo4类继承SimpleTagSupport 12 */ 13 public class SimpleTagDemo4 extends SimpleTagSupport { 14 15 /* 简单标签使用这个方法就可以完成所有的业务逻辑 16 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 17 * 重写doTag方法,控制标签余下的Jsp不执行 18 */ 19 @Override 20 public void doTag() throws JspException, IOException { 21 //抛出一个SkipPageException异常就可以控制标签余下的Jsp不执行 22 throw new SkipPageException(); 23 } 24 }
在WEB-INF目录下的simpletag.tld文件中添加对该标签处理类的描述,如下:
1 <tag> 2 <!-- 标签名 --> 3 <name>demo4</name> 4 <!-- 标签处理器类--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo4</tag-class> 6 <!-- 标签体允许的内容 ,empty表示该标签没有标签体--> 7 <body-content>empty</body-content> 8 </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>用简单标签控制标签余下的Jsp不执行</title> 10 </head> 11 12 <body> 13 <h1>孤傲苍狼</h1> 14 <%--在jsp页面中使用自定义标签 --%> 15 <gacl:demo4/> 16 <!-- 这里的内容位于 <gacl:demo4/>标签后面,因此不会输出到页面上 --> 17 <h1>白虎神皇</h1> 18 </body> 19 </html>
运行效果如下:
五、简单标签开发的一些注意细节
5.1、标签类编写细节
开发标签类时,不要直接去实现SimpleTag接口,而是应该继承SimpleTagSupport类,SimpleTagSupport类是SimpleTag接口的一个默认实现类,通过继承SimpleTagSupport类,就可以直接使用SimpleTagSupport类已经实现的那些方法,如果SimpleTagSupport类的方法实现不满足业务要求,那么就可以根据具体的业务情况将相应的方法进行重写。
5.2、tld文件中标签体类型设置细节
我们开发好一个简单标签后,需要在tld文件中添加对该标签的描述,例如:
1 <tag> 2 <!-- 标签名 --> 3 <name>demo2</name> 4 <!-- 标签处理器类--> 5 <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class> 6 <!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码--> 7 <body-content>scriptless</body-content> 8 </tag>
开发好一个标签后,在tld文件中使用<tag>来描述一个标签,描述的内容包括标签名(name),标签处理器类(tag-class),标签体的内容(body-content)。
tld文件中有四种标签体(body-content)类型 :empty、JSP、scriptless、tagdependent
简单标签标签体的细节注意问题:
在简单标签(SampleTag)中标签体body-content的值只允许是empty、scriptless、tagdependent,不允许设置成JSP,如果设置成JSP就会出现异常:
1 The TLD for the class me.gacl.web.simpletag.SimpleTagDemo1 specifies an invalid body-content (JSP) for a SimpleTag
body-content的值如果设置成empty,那么就表示该标签没有标签体,如果是设置成scriptless,那么表示该标签是有标签体的,但是标签体中的内容不可以是<%java代码%>,例如:
1 <gacl:xdpdemo1> 2 <% 3 //嵌套在标签体中的java代码 4 int i= 0; 5 %> 6 孤傲苍狼 7 </gacl:xdpdemo1>
否则运行标签时就会出现如下错误:
1 Scripting elements ( <%!, <jsp:declaration, <%=, <jsp:expression, <%, <jsp:scriptlet ) are disallowed here
jsp标签技术出现的目的就是为了移除在jsp页面上编写的java代码的,如果在jsp标签中允许出现java代码,那么就违背了jsp标签技术设计时的初衷了。所以在简单标签的标签体中是不允许出现java代码的。
传统标签标签体的细节注意问题:
在传统标签中标签体body-content的值允许是empty、JSP、scriptless、tagdependent,body-content的值如果是设置成JSP,那么表示该标签是有标签体的,并且标签体的内容可以是任意的,包括java代码,如果是设置成scriptless,那么表示该标签是有标签体的,但是标签体的内容不能是java代码
如果传统标签和简单标签的标签体body-content的值设置成tagdependent,那么就表示标签体里面的内容是给标签处理器类使用的,tagdependent用得比较少,了解一下即可
5.3、tld文件中标签库的uri设置细节
如果在一个项目中使用或者开发了多个标签库,例如:
那么标签库的uri不能设置成相同的,否则在Jsp页面中通过uri引用标签库时就不知道引用哪一个标签库了,如果真的有那么巧,两个标签库的uri是刚好一样的,如下图所示:
那么在jsp页面中引用标签库时如果"<%@taglib uri="/gacl" prefix="gacl" %>"这样引用,那么就无法判断当前引用的标签库到底是gacl.tld标签库中的标签还是simpletag.tld标签库中的标签,因为两个标签库的uri刚好都是"/gacl",在两个标签库的引用uri一样的情况下,为了能够在jsp中区别到底引用的是哪个标签库,可以换一种引用方式:<%@taglib uri="要引用的标签库的tld文件目录" prefix="gacl"%>,使用taglib指令引入标签库时,taglib指令的uri属性指定为标签库的tld文件目录,这样就可以区别开了,例如:
引用gacl.tld标签库:<%@taglib uri="/WEB-INF/gacl.tld" prefix="gacl"%>、
引用simpletag.tld标签库:<%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%>
所以当在项目中引用了多个标签库,如果标签库的uri刚好是一样的,就可以用这种方式解决。
六、简单标签开发步骤总结
1、编写一个类继承SimpleTagSupport类,然后根据业务需要重写SimpleTagSupport类中已经实现了的方法,一般情况下只需要重写doTag()方法即可。
2、在WEB-INF目录下创建一个tld文件,在tld文件中添加对该标签的描述。tld文件不一定放在WEB-INF目录下,也可以放在别的目录,习惯是放在WEB-INF目录下。
javawen学习自定义标签开发相关推荐
- 转载:javaweb学习总结(二十三)——jsp自定义标签开发入门
javaweb学习总结(二十三)--jsp自定义标签开发入门 转自:http://www.cnblogs.com/xdp-gacl/p/3916734.html 一.自定义标签的作用 自定义标签主要用 ...
- javaweb学习总结(二十三)——jsp自定义标签开发入门
一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...
- javaweb学习总结(二十三):jsp自定义标签开发入门
一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...
- JSP自定义标签开发与打包
前言:最近用到JSP的自定义标签,于是到网上寻找资料,结果发现很多的网上教程要么不全要么就是步骤流程错误,尤其是将自定义标签打jar包这一过程,按照网上的教程操作,结果被坑惨了,所以才有现在这一篇博文 ...
- JSP自定义标签开发入门
一般情况下开发jsp自定义标签需要引用以下两个包 import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; 首先我们需要大致了解开发 ...
- 【自定义标签开发】01-标签简介和开发第一个标签
自定义标签简介 自定义标签主要用于移除Jsp页面中的java代码. 要使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤: 1.编写一个实现Tag接口的java类,把页面java代码 ...
- JSP自定义标签开发(五)——标签类获取 request 、 session
标签类中要是能够取到 request 和 session 这样的对象,对于一个web开发员来说,那是一件多么幸福的事情啊!懂得了这个知识,标签开发与servlet结合的开发将变得随心所欲. 实例: p ...
- java web 自定义标签_JavaWeb学习——自定义标签
自定义标签 一.自定义标签概述 使用标准JSP访问.操作JavaBean,是实现展现(HTML)与业务实现(Java代码)分离的第一步.然而,标准方法功能不够强大,以至于开发者无法仅仅使用它们开发应用 ...
- pbootcms自定义标签开发_替换标题中的特殊符号
如题:最新在使用pbootcms进行建站,现有的标签不符合自己的一些业务需求,想着自己做个符合自己的业务的标签,于是参考了一下网上的资料以后便开始着手开发了,整个二开还是比较简单,下面放出来需要修改的 ...
最新文章
- AJAX ControlToolkit学习日志-ModalPopupExtender(16)
- Oracle 11gR2构建RAC之(3)--安装grid前环境检测
- 【转】北京四中学习方法
- elecV2P实现任务定时通知
- prefixspan是挖掘频繁子序列,子序列不一定是连续的,当心!!!
- 从宏观经济状况看目前股市
- windows下qt5 kinect 2.0开发与环境配置
- Framework学习(二)Android的启动过程
- Rational AppScan 标准版可扩展性和二次开发能力简介
- CQOI 2016 不同的最小割
- 中国人民公安大学(PPSUC) 网络对抗技术作业一
- win10系统dnf安装不上服务器,升级到Win10正式版后不能玩DNF如何解决?
- 不应被忘记的历史——聊聊前阿布时代的切尔西
- Ubuntu 10.04 HP LaserJet 无法打印 **** Unable to open the initial device, quitting 错误
- 计算机故障四类,计算机内存出现问题的四大症状
- SpringBoot项目的云服务器部署
- 某公司公众号任意用户注册漏洞利用
- Messaging短信源码导入AndroidStudio
- js随机字符a-zA-Z0-9
- shell之read用法
热门文章
- 小米手机图标消失问题
- 企业为什么要申报高新技术企业
- 深聊全链路压测之:第二十三讲 | 如何改造性能监控。
- 洛谷——P1017 [NOIP2000 提高组] 进制转换(C++)
- 基于Matlab——夫琅禾夫衍射以及菲涅尔衍射
- 打印机驱动冲突和端口异常:win10更新部分补丁后,打印机本地连接(连接打印机的主机)可以打印,其他共享网络中的电脑可以连接到打印机,但不能打印——解决方案
- cubemx 使用 学习跳转链接
- TI 280049 FLASH 翻译
- 写给初入行,刚接触Auto CAD的新人一些建议——第一期
- Linux学习5之查找文件中的某个字符串并返回所在行号