JavaWeb开发技术学习笔记(十三)——自定义标签

传统方式(了解)

1.步骤:a.编写标签处理类 b.编写标签描述符 c.导入并使用

a.编写标签处理类
传统方式(JSP1.1):实现javax.servlet.jsp.tagext.Tag接口 doStartTag()
简单方式(JSP2.0):实现javax.servlet.jsp.tagext.SimpleTag接口 doTag()

​ 如果jsp在编译阶段 发现了自定义标签<xx:yyy > ,就会交给doStartTag()或doTag()

b.编写标签描述符 tld

​ 编写建议:可以仿照一个 其他标签语言(el jstl ) 的tld文件

c.导入并使用
位置:myTag.tld导入 WEB-INF或子目录下WEB-INF/abc/ (特例排除,不能是WEB-INF/lib、WEB-INF/classes )
使用:
引入具体要使用的.tld文件
<%@ taglib uri="…" prefix=“d” %>
uri:每个tld文件的 唯一描述符
prefix:使用tld标签时 的前缀
myTag1.tld
myTag2.tld
myTag3.tld

具体的使用:
a.空标签(没有标签体的标签)
<d:foreach></d:foreach>
<d:foreach />

​ b.带标签体
<d:foreach> xxx </d:foreach>
​ c.带属性
<d:foreach 属性名=“属性值” > xxx </d:foreach>
<d:foreach collection="${students}" > xxx </d:foreach>

​ d.嵌套
​ <d:foreach>
​ <d:foreach> xxx </d:foreach>
​ </d:foreach>

<d:foreach>
xxx
<d:…>

<%xxx%>

实际开发步骤:
a.编写标签处理类
先确保项目有tomcat环境
Tag接口:
doStartTag():标签处理类的核心方法 (标签体的执行逻辑)
该方法有以下2个返回值: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 realease(),用于解析标签的执行逻辑。

javax.servlet.jsp.tagext.IterationTag接口:(是Tag的子接口)
如果有循环:IterationTag,
没有循环:Tag
IterationTag接口中存在以下方法:
doAfterBody():当标签体执行完毕之后的操作 ,通过返回值决定 :
(EVAL_BODY_AGAIN = 2)要么重复执行 ;
(SKIP_BODY=0):要么不再执行
目标:遍历3次 (hello)

hello
执行一次,并重复两次

b.编写标签描述符
myTag.tld

c.导入并使用

<%@ taglib uri=“http://www.yanqun.com” prefix=“yq” %>

hello

</yq:mytag>

jstl: <c:foreach …> </…> 使用
<yq:mytag num=“3”> 处理类,tld,使用

BoyTag接口:如果在标签体 被显示之前,进行一些其他的“额外”操作
hello hello hello -> HELLO HELLO HELLO
包含属性:
int EVAL_BODY_BUFFERED = 2, 是doStartTag()的第三个返回值 ,代表一个缓冲区(BodyContent)。

BodyContent是abstract,具体使用时需要使用实现类 BodyContentImpl(再引入jasper.jar)

缓冲区(BodyContent)的使用用途:hello ->HELLO

如果返回值是EVAL_BODY_BUFFERED ,则服务器会自动 将标签体需要显示的内容 放入缓冲区中(BodyContent)

。因此,如果要更改最终显示结果,只需要从 缓冲区 获取原来的数据 进行修改即可。
如何修改、获取 缓冲区:详见BodyContent的方法,具体就是 通过getXxx()获取原来的数据(hello),自己修改(HELLO),输出getEnclosingWriter();

a.编写标签处理类
b.编写标签描述符 c.导入并使用

简单方式

SimpleTag
最大的简化:
将传统方式的doStartTag() doEndTag() doafterBody()等方法 简化成了一个通用的 doTag()方法。

doTag() :传统方式 可以对标签的最终显示 进行修改, hello ->HELLO ,核心是有一个缓冲区。
但是简单方式 没有“缓冲区”。 如何修改显示内容? 流

javax.servlet.jsp.tagext.JspFragment类 :代表一块JSP元素(该块 不包含scriptlet,因此简单方式的tld文件中不能是JSP )

JspFragment中有一个invoke(Writer var1) 方法,入参是 “流”,即如果要修改显示内容,只需要修改此 流

invoke(Writer var1) :每调用一次invoke()方法,会执行一次 标签体。

SimpleTagSupport的 getJspBody()可以获取JspFragment对象。
SimpleTagSupport的 getJspContext()方法 可以获取 jsp一些内置对象:getJspContext()的返回值是JspContext对象 是JSP内置对象的入口对象PageContext 的父类。

简单标签方式 ,获取JSP内置对象: getJspContext() -> JspContext ->转成子类PageContext ->PageContext就是所有JSP内置对象的入口,即可以获取一切JSP内置对象

条件选择:
当某一个条件满足时,再执行某个标签体
传统标签:如果条件不满足,让doStartTag()的返回值为0;
简单标签(不允许写scriplet <% …%>): 如果条件不满足,不调用invoke()即可。

JSP内置对象

条件选择:
当某一个条件满足时,再执行某个标签体
传统标签:如果条件不满足,让doStartTag()的返回值为0;
简单标签(不允许写scriplet <% …%>): 如果条件不满足,不调用invoke()即可。

猜你喜欢

转载自blog.csdn.net/MACRosshaha/article/details/105871269