1.为什么要使用自定义标签
我们在Javaweb中常常会用到一些jsp的标签,比如<c:foreach>、<c:if>、<fmt:formatDate>等标签,但是sun公司提供的这些标签虽然能够满足我们大部分的应用需求,但是对于一些特殊应用需求就不能满足了,这时候我们就需要自定义一些我们自己的标签库。
2.自定义标签的作用
--用于移除jsp页面的Java代码
--控制jsp页面某一部分内容是否执行(内容权限控制)
--控制整个jsp页面是否执行(页面权限控制)
--控制jsp页面内容(标签体)重复执行
--修改jsp页面的内容输出
3.标签语言特点
标签是由<开始标签>标签体</结束标签>三部分组成
也会分为空标签和标准标签
空标签:<开始标签/> 例如:<br/> 也就是单标签
标准标签:<开始标签>标签体<结束标签/> 例如:<a></a>
4.自定义标签开发及使用步骤
第一步 创建助手类,并继承BodyTagSupport
public class TestTag extends BodyTagSupport { }
第二步 在WEB-INF或其子目录下导入或创建标签描述文件tld
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<!-- 代表标签库的版本号 -->
<tlib-version>1.0</tlib-version>
<!-- 代表jsp的版本 -->
<jsp-version>1.2</jsp-version>
<!-- 你的标签库的简称 -->
<short-name>z</short-name>
<!-- 你标签库的引用uri -->
<uri>/zking</uri><tag>
<!-- 标签名 -->
<name>标签名</name>
<!-- 标签工具类 -->
<!-- 利用反射机制,通过Class.forName(类的全路径名/包名+类名)的方式反射机制实例化标签助手类 -->
<tag-class>com.zking.tag.PaginationTag</tag-class>
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>empty</body-content>
<!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 -->
<attribute>
<!-- 自定义标签的属性名称 -->
<name>属性名</name>
<!-- true表示必填 false表示可有可无-->
<required>true</required>
<!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
红色字体的 z 和 /zking 对应的是 <%@taglib prefix="z" uri="/zking" %>
绿色字体的 com.zking.tag.PaginationTag 是我们创建的助手类的全路径
棕色字体的 标签名 和 属性名 相对应的是 <z:pagination pageBean=" 必填 "/>
标签助手类中的属性名称要与描述文件中的属性名称一致 ,必须要提供get/set方法
没有属性的自定义标签<attribute>标签内的可以不要,给去掉
要是不止一个标签名就重复写<tag>标签内的
第三步 在指定的jsp页面中引入之定义标签
<%@taglib prefix="z" uri="/zking" %>
5.自定义标签的生命周期
继承BodyTagSupport后,重写doStartTag()方法和doEndTag()方法
doStartTag():doStartTag方法对应开始标签所执行的动作
返回值:
EVAL_BODY_INCLUDE:计算标签体内容并包含在输出中
SKIP_BODY:跳过标签体内容不输出
doEndTag():doEndTag方法对应结束标签所执行的动作
返回值:
SKIP_PAGE:跳过页面的后续内容(一般不用,因为会把页面后的内容给去掉)
EVAL_PAGE:计算页面的后续内容
重写doAfterBody()方法,是用在循环里的
doAfterBody():doAfterBody 介于<开始标签>标签体和<结束标签>之间所执行的动作
返回值:
EVAL_BODY_AGAIN:再次计算输出标签体内容
SKIP_BODY:跳过标签体内容不输出(相当于终止循环)
6.自定义test标签
先在创建标签描述文件tld中设置text标签
<tag> <!-- 标签名 --> <name>test</name> <!-- 标签工具类 --> <tag-class>com.zking.tag.TestTag</tag-class> <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 --> <body-content>jsp</body-content> <!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 --> <attribute> <!-- 自定义标签的属性名称 --> <name>name</name> <!-- true表示必填 --> <required>false</required> <!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 --> <rtexprvalue>false</rtexprvalue> </attribute> </tag>
然后就去助手类中继承BodyTagSupport,定义name属性,并提供get/set方法
继续定义一个Integer类型的count=0,方便我们去循环
再重写doStartTag()方法和doEndTag()方法(可以重写doAfterBody()方法,也可以不重写)
@Override public int doStartTag() throws JspException { this.count=0; System.out.println("<开始标签>所执行的动作doStartTag"); System.out.println("name属性"+this.name); return EVAL_BODY_INCLUDE; }
this.count=0; 保证每次 doAfterBody()循环中都会小于3
返回 EVAL_BODY_INCLUDE(计算标签体内容并包含在输出中)
@Override public int doAfterBody() throws JspException { if(this.count<3){ this.count++; System.out.println("介于<z:test>111和</z:test>之间所执行的动作"); return EVAL_BODY_AGAIN; } return SKIP_BODY; }
判断数量是否小于3,返回的是 EVAL_BODY_AGAIN(再次计算输出标签体内容)
最外面的返回的是 SKIP_BODY(跳过标签体内容不输出(相当于终止循环))
@Override public int doEndTag() throws JspException { System.out.println("<结束标签>所执行的动作doEndTag"); return EVAL_PAGE; }
返回 EVAL_PAGE(计算页面的后续内容)
写完结束标签后,就返回页面中写我们自己定义的标签了
<h3>1.自定义test标签</h3> <z:test name="zking">123</z:test> <div>122222</div>
就会出现这样的效果了 ,标签体被循环了三次
但是为什么会有四次呢?是因为我们返回的是 EVAL_BODY_INCLUDE(计算标签体内容并包含在输出中),所以就会出现四次
JSP自定义标签到这里就讲完了ヾ(≧▽≦*)o