步骤:a.编写标签处理类 b.编写标签描述符 c.导入并使用
a.编写标签处理类
传统方式(JSP1.1):实现tag接口 doStarTag()
简单方式(JSP2.0):实现Simple接口 doTag()
如果jsp在编译阶段发现了自定义标签<xx:yyy>,就会交给doStartTag()或doTag()
b.编写标签描述符 tld
编写建议:可以仿照一个其他标签语言(el jstl)的tld文件
c.导入并使用
位置:myTag.tld导入 导入WEB-INF或其子目录下(特例排除,不能是WEB-INF/lib、WEB-INF/classes)
使用;
引入具体要使用的.tld文件
<% @taglib uri="..." prefix="d" %>
uri:每个tld文件的唯一描述符
prefix:使用tld标签时的前缀
具体的使用:
a.空标签(没有标签体的标签)
<d:foreach></d:foreach>
<d:foreache/>
b.带标签体
<d:foreach>xxx</d:foreach>
c.带属性
<d:foreach 属性名="属性值">xxx</d:foreach>
<d:foreach collection="${students}">xxx</d:foreach>
d.嵌套
<d:foreach>
<d:foreach>xxxx</d:foreach>
</d:foreach>
实际开发步骤:
a.编写标签处理类
先确保项目有tomcat环境
Tab接口:
doStartTag():标签处理类的核心方法(标签体的执行逻辑)
该方法有一下两个返回值:0/1
int SKIP_BODY = 0;标签体不会被执行
int EVAL_BODY_INCLUDE = 1;标签体会被执行
doEndTag():标签执行完毕之后的方法。例如可以让标签在执行完毕之后,再执行一次
int SKIP_PAGE = 5;后面的JSP页面内容不被执行
int EVAL_PAGE = 6;后面的JSP页面内容继续执行
Tag接口中的所有方法执行顺序:
jsp-servlet
当JSP容器(Tomcat、jetty)在将.jsp翻译成.servlet(.java)的时候,如果遇到JSP中有标签
就会依次执行setPageContext()、setParent()、doStartTag()、doEndTag()、release()用于解析标签的执行逻辑
javax.servlet.jsp.tagext.IterationTag接口:(Tag的子接口)
如果有循环;IterationTag
没有循环;Tag
IterationTag接口中存在以下方法:
doAfterBody():当标签体执行完毕之后的操作,通过返回值决定:
EVAL_BODY_AGAIN=2重复执行
SKIP_BODY = 0不再执行
目标:遍历3次
<xxx>hello<xxx>
执行一次,并重复两次
b.编写标签描述符
myTag.tld
c.导入并使用
<%@ taglib uri="http://www.myy.com" prefix="myy" %>
<body>
<myy:MyTag num="3">myy</myy:MyTag>
</body>
BodyTag接口:如果在标签体被显示之前,进行一些其他的“额外”操作
myy myy myy->MYY MYY MYY
包含属性:
int EVAL_BODY_BUFFERED=2; 时doStartTag()的第三个返回值,代表一个缓存区(BodyContent)。
BodyContent是abstract,具体使用时需要实现类BodyContentImpl(再引入jasper.jar)
缓存区(BodyContent)的使用用途:hello->HELLO
如果返回值是EVAL_BODY_BUFFERED,则服务器会自动将标签体需要显示的内容放入缓冲区中(BodyContent)
因此,如果要更改最终显示结果,只需要从缓存区获取原来的数据,进行 修改即可。
如何修改、获取缓冲区:详见BodyContent的方法,具体就是通过getXxx()获取原来的数据,自己修改,输出getEnclosingWriter();