王晓斌的专栏

Take honour from me and my life is undone.

【Java.Web】JSP —— 标签库taglib —— 自定义JSP标签 —— JSP Tag API

JSP Tag API

Servlet 容器在运行翻译JSP文件时,如果遇到自定义标签,就会调用这个标签的处理类(Tag Handler Class)的相关方法。

标签处理类可以继承JSP Tag API中的TagSupport类或者BodyTagSupport类。

Package javax.servlet.jsp.tagext


该Package中主要类和接口如下:




标签处理类的对象(Tag对象)有Servlet容器负责创建。Servlet容器在执行JSP文件时,如果遇到JSP文件中的自定义标签,就会寻找缓存中的相关Tag对象,如果还不存在,就创建一个Tag对象,把它放在缓存中,以便下次处理自定义标签时重复使用。

一个Tag对象在被创建后,就会一直存在可以被Servlet容器反复调用,当Web应用终止时,调用所有Tag对象的release()方法,然后销毁这些Tag对象。



JspTag接口

public interface JspTag

所有的标签处理类都要实现JspTag接口。这个接口只是一个标识接口,没有任何方法,主要是作为Tag和SimpleTag接口的共同接口。

  • 实现Tag接口的标签成为传统标签(Classis Tag)
  • 实现SimpleTag接口的标签成为简单标签(Simple Tag)


Tag接口

public interface Tag
extends JspTag

Tag接口定义了所有传统标签处理类都要实现的基本方法:

  • setPageContext(PageContext pc) —— 由Servlet容器调用该方法,向前标签处理对象(即Tag对象)传递当前的PageContext对象
  • setParent(Tag t) —— 由Servlet容器调用该方法,向当前Tag对象传递父标签的Tag对象
  • getParent() —— 返回Tag类型的父标签的Tag对象
  • release() —— 当Servlet容器需要释放Tag对象占用的资源时,会调用此方法
  • doStartTag() —— 当Servlet容器遇到标签的其实标志时,会调用此方法。其返回一个整数值,用来决定程序的后续流程。返回Tag.SKIP_BODY表示标签之间的主体内容被忽略,返回Tag.EVAL_BODY_INCLUDE表示标签之间的主体内容被正常执行
  • doEndTag() —— 当Servlet容器遇到标签的结束标志时,就会调用此方法。其也返回一个整数值,用来决定程序的后续流程。返回Tag.SKIP_PAGE表示立刻停止执行标签后面的JSP代码,网页上未处理的静态内容和Java程序片段均被忽略,任何已有的输出内容立刻返回到客户端的浏览器上;返回Tag.EVAL_PAGE表示按正常的流程继续执行JSP文件


当Servlet容器得到了Tag对象之后,按照下面的流程调用Tag对象的相关方法:

  • Servlet容器调用Tag对象的setPageContext()和setParent()方法,把当前JSP页面的PageContext对象及父标签处理对象传给当前的Tag对象。如果不存在,则把父标签处理对象设为null
  • Servlet容器调用Tag对象的一系列set方法,设置Tag对象的属性
  • Servlet容器调用Tag对象的doStartTag()方法
  • 如果doStartTag()方法返回Tag.SKIP_BODY,就不会执行标签主体的内容;如果返回Tag.EVAL_BODY_INCLUDE,就执行标签主体的内容
  • Servlet容器调用Tag对象的doEndTag()方法
  • 如果doEndTag()方法返回Tag.SKIP_PAGE,就不执行标签后续的JSP代码;如果返回Tag.EVAL_PAGE,就执行后续的JSP代码




IterationTag接口

public interface IterationTag
extends Tag


IterationTag接口增加了重复执行标签主体内容的功能。

IterationTag接口定义了一个doAfterBody()方法,Servlet容器在执行完标签主体内容后,会调用此方法。如果Servlet容器未执行标签主体内容,那么就不会调用此方法。doAfterBody()方法也返回一个整数值,用来决定程序后续流程;返回Tag.SKIP_BODY表示不再执行标签主体的内容;返回IterationTag.EVAL_BODY_AGAIN表示重复执行标签主体的内容。

Servlet容器按照如下流程调用IterationTag对象的相关方法:




BodyTag接口

public interface BodyTag
extends IterationTag


BodyTag接口增加了直接访问和操纵标签主体内容的功能。

BodyTag接口新增了两个方法:

  • setBodyContent(BodyContent bc) —— Servlet容器通过此方法向BodyTag对象传递一个用户缓存标签主体执行结果的BodyContent对象;
  • doInitBody() —— 当Servlet容器调用完setBodyContent()方法之后,在第一次执行标签主体之前,先调用此方法,该方法用于执行标签主体的初始化工作

当符合下面条件时,setBodyContent()和doInitBody()方法就不会被Servlet容器调用:

  • 标签主体为空
  • doStartTag()方法的返回值为Tag.SKIP_BODY或者Tag.EVAL_BODY_INCLUDE

只有同时符合一下两个条件,Servlet容器才会调用这个两个方法:

  • 标签主体不为空
  • doStartTag()方法的返回值为BodyTag.EVAL_BODY_BUFFERED


Servlet容器按照如下的流程调用BodyTag对象的相关方法:





TagSupport类和BodyTagSupport类

public class TagSupport
extends Object
implements IterationTag, Serializable

public class BodyTagSupport
extends TagSupport
implements BodyTag


TagSupport类和BodyTagSupport类是标签实现类;用户自定义的标签处理类可以继承TagSupport类或者BodyTagSupport类。


TagSupport类的主要方法:

  • doStartTag() —— 当Servlet容器遇到自定义标签的起始标志时调用
  • doEndTag() —— 当Servlet容器遇到自定义标签的结束标志时调用
  • setValue(String key, Object value) —— 在标签处理对象中设置key/value
  • getValue(String key) —— 根据参数key返回匹配的value
  • removeValue(String key) —— 在标签出路对象中删除key/value
  • setPageContext(PageContext pc) —— 设置PageContext对象,该方法由Servlet容器在调用doStartTag()方法前调用
  • getParent() —— 返回父标签的处理对象


TagSupport类的成员变量:

  • parent —— 代表父标签的处理对象
  • pageContext —— 代表当前JSP页面的PageContext对象
  • Servlet容器在调用doStartTag()之前,会先调用setPageContext()和setParent()方法,设置pageContext和parent成员变量;其余的方法可直接使用;
  • 在TagSupport的构造方法中不能访问pageContext对象,因为此时Servlet容器还没有对pageContext成员进行初始化


主要重新实现的TagSupport类的方法:

对于用户自定义的标签处理类,主要重新实现TagSupport类中的以下方法,

  • doStartTag() —— 
  • doEndTag() ——
  • 如果希望Servlet容器重复执行标签主体的内容,那么还可以重新实现TagSupport类的doAfterBody()方法


用户自定义的标签属性:

如果在标签中包含自定义的属性,那么在标签处理类中应该将这个属性作为成员变量,并且分别提供设置读取属性的方法,

例如:

<prefix:mytag username="New User">
    ... ...
</prefix:mytag>


private String username;
public void setUsername(String username){
	this.username = username;
}
public String getUsername(){
	return usrname;
}


操纵标签主体内容:

如果希望操纵标签主体内容,可以让自定义的标签处理类继承BodyTagSupport类。

BodyTagSupport类有一个重要的bodyContent成员变量,用于缓存标签主体的执行结果。

如果标签处理类doStartTag()方法返回BodyTag.EVAL_BODY_BUFFERED,那么Servlet容器在执行标签主体之前,会先创建一个用来缓存标签主体执行结果的BodyContent对象,接着调用setBodyContent()方法,使得成员变量bodyContent引用BodyContent对象;然后再调用doInitBody()方法。Servlet容器在执行标签主体内容时,会把得到的执行结果缓存到BodyContent对象中。










阅读更多
文章标签: Java Web
个人分类: Java.Web
想对作者说点什么? 我来说一句

JSP+JSTL+TagLib API帮助文档.CHM

2008年07月10日 584KB 下载

没有更多推荐了,返回首页

不良信息举报

【Java.Web】JSP —— 标签库taglib —— 自定义JSP标签 —— JSP Tag API

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭