自定义标签可以实现的功能:
- 移除jsp中的java代码
- 控制jsp中的某段程序是否执行
- 控制jsp页面中的所有内容是否执行
- 控制jsp中的程序重复执行
- 修给jsp中的内容。
传统标签库 总结:
创建传统标签
- 创建jsp标签类继承
TagSupport
类。 - 重写
doStartTag()
方法,在doStartTag()
方法中书写程序,此方法在执行开始标签的时候被服务器调用。服务器在遇到标签的时候先调用tag类的setPageContext(pageContext)
方法将pageContext类传递进去。 - 在WEB-INF下创建tld文件,在文件中对标签进行配置。
<?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/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
//将此标签绑定的uri,通过此uri引用标签
<uri>http://www.baixinping.com</uri>
<tag>
<description>Outputs Hello, World</description>
//引用时的名称
<name>ha</name>
//标签类的目录
<tag-class>baixinping.tag.Ha</tag-class>
//标签体中是否有内容
<body-content>empty</body-content>
</tag>
</taglib>
- 使用:
<%@ taglib uri="http://www.baixinping.com" prefix="ha" %>
控制jsp中的某段程序的输出:
1、继承TagSupport
2、重写doStartTag();
3、如果doStartTag()
返回TagSupport.SKIP_BODY
,则不执行标签体中的内容,如果返回的是TagSupport.EVAL_BODY_INCLUDE
则执行标签体中的内容。
控制jsp页面是否执行。
- 继承
TagSupport
- 重写
doEndStart()
- 如果
doEndTag()
返回TagSupport.SKIP_PAGE
,则不执行余下的jsp中的内容。如果返回TagSupport.EVAL_PAGE
,则继续执行余下的内容。
控制部分代码重复执行
- 继承继承
TagSupport
- 重写
doAfterBody()
方法,此方法在执行完标签体中的内容之后执行。 - 如果
doAfterBody()
方法返回TagSupport.EVAL_BODY_AGAIN
,则继续执行标签体中的内容。如果返回TagSupport.SKIP_BODY
则继续执行doEndTag()
方法。
修改jsp中的内容
- 继承
BodyTagSupport
。此类在执行完doStartTag()
完之后会自动执行setBodyContent()
方法将标签体中的内容传递给标签类。然后执行doEndTag
方法。 - 在
doEndTag()
方法中通过this.getBodyContent()
获取标签体内容对象,然后对其进行修改即可。
简单标签库使用 总结:
继承SimpleTagSupport
。tld文件中声明有标签体使用<body-content>scriptless</body-content>
,意思是标签体中不能有脚本代码(java程序)
简单标签执行步骤(原理):
- 遇到简单标签之后,先实例化标签类。
- 调用
setJspContext()
将pageContexr()
将jsp页面对象传递过来。 - 调用
setParent()
方法将标签的父标签传递过来,如果没有父标签传递null. - 调用
setJspBody()
将封装了标签体内容的JspFragment
对象传递过来。 - 执行标签(调用
doTag()
方法),控制标签之后的内容不被执行,只需要抛出new SkipPageException()
即可。
JspFragment content = this.getJspBody();
content.invoke(this.getJspContext().getOut());
使用invoke()方法将内容写入对应的流缓冲区中。 - 垃圾回收器回收标签对象(在传统标签中,标签对象会驻留在内存中继续服务之后的调用)
标签定义属性:
- 在标签类中创建属性值,并创建set方法。
- 在tld文件中声明属性。
<tag>
<description>Outputs Hello, World</description>
<name>test6</name>
<tag-class>baixinping.tag.Test6</tag-class>
<body-content>scriptless</body-content>
<attribute>
//属性名
<name>count</name>
//属性是否必须
<required>true</required>
//属性值是否可以使用表达式
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
注意:set方法会自动有服务器调用,服务器赋值只能够进行8中基本数据类型转换。若是复杂类型,则在jsp页面中使用表达式。