简单的标签API
SimpleTag接口与传统标签接口最大的区别在于:SimpleTag接口中只定义了一个用于处理标签逻辑的doTag方法,该方法用于取代传统标签接口中定义的doStartTag()、doEndTag()和doAfterBody()等方法。doTag()方法在JSP引擎执行自定义标签时调用,并且只被调用一次,那些使用传统标签接口所能完成的功能,例如是否执行标签体、迭代输出标签体、对标签体内容进行修改等功能都在doTag()方法体内完成。
接下来,首先对在开发简单标签时需要用到一些接口和类进行介绍,具体如下:
1、SimpleTag接口
SimpleTag是所有简单标签处理器的父接口,它共定义了5个方法,具体如表1所示。
表1 SimpleTag接口的常用方法
方法声明 | 功能描述 |
---|---|
void setJspContext(JspContext pc) | 用于将JSP页面的内置对象pageContext对象传递给标签处理器,标签处理器可以通过pageContext对象与JSP页面进行通信。JSPContext类是PageContext类的父类,其中定义了一些不依赖于Servlet运行环境的方法,setJspContext()方法接收的参数类型为JspContext,是为了便于将简单标签扩展应用到非Servlet运行环境中 |
void setParent(JspTag parent) | 用于将当前标签的父标签处理器对象传递给当前标签处理器,如果当前标签没有父标签,JSP容器不会调用这个方法 |
JspTag getParent() | 返回当前标签的父标签处理器对象,如果当前标签没有父标签则返回null |
void setJspBody(JspFragment jspBody) | 用于把代表标签体的JspFragment对象传递给标签处理器对象 |
void doTag() | 用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag()方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知JSP容器不再执行JSP页面中位于结束标签后面的内容,这等效于在传统标签的doEndTag()方法中返回SKIP_PAGE常量 |
从表9-4中可以看出,SimpleTag接口中的方法和传统标签接口中定义的方法签名有所区别,但是功能却基本一致,例如都实现了给标签处理器传递PageContext对象和父标签处理器对象的功能,而且JSP容器执行简单标签处理器的顺序也和执行传统标签处理器的顺序一致。简单标签处理器的执行流程如图1所示。
图1 标签处理器的执行流程
需要注意的是,JSP规范要求JSP容器在每次处理JSP页面中的简单标签时,都需要创建一个独立的简单标签处理器实例对象,而不会像传统标签那样对标签处理器对象进行缓存,因此简单标签也是线程安全的。
2、JspFragment类
javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中一段JSP片段,但是这段JSP片段中不能包含JSP脚本元素。
JSP容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody()方法将JspFragment对象传递给标签处理器对象,标签开发者可以根据需要调用JspFragment对象的方法来决定是否输出标签体、或者循环多次输出标签体等。在JspFragment类中定义了两个方法,方法的说明如表2所示。
表2 JspFragment类的方法
方法声明 | 功能描述 |
---|---|
JspContext getJspContext() | 用于返回代表调用页面的JspContext对象 |
void invoke(Writer out) | 用于将标签体内容写入到指定的输出流对象out 中,如果调用该方法时传入的参数为null,JSP容器会将标签内容写入到JspContext.getOut()方法返回的输出流对象中。 |
在表2中,JspFragment的invoke()方法是简单标签开发中最重要的一个方法,它用于控制如何执行标签体的内容。如果在doTag()方法中调用一次invoke()方法,就会执行一次标签体,多次调用invoke()方法就会多次执行标签体。与BodyContent对象不同的是在JspFragment中没有提供容器缓存标签体内容,也没有定义getString()之类的方法取出标签体内容,如果想对标签体内容进行修改,只需在调用invoke()方法时传入一个可取出结果数据的输出流对象,例如StringWriter、CharArrayWriter,让标签体的执行结果输出到该输出流对象中,然后取出数据进行修改后再输出到浏览器即可。
3、SimpleTagSupport
为了简化简单标签处理器的编写,JSP规范中定义了一个类SimpleTagSupport,该类实现了SimpleTag接口,它内部使用成员变量jspContext和jspBody引用了JSP容器传入的JspContext对象和JspFragment对象,并且提供了两个方法来返回这两个对象的引用,具体如表3所示。
表3 SimpleTagSupport类的方法
方法声明 | 功能描述 |
---|---|
JspContext getJspContext() | 用于返回代表调用页面的JspContext对象 |
JspFragment getJspFragment() | 用于返回代表标签体的JspFragment对象 |