在继续详述标签接口及类之前,先回忆一下定制标签的总体的调用机制。见图:(其中蓝色为声明过程,红色为调用过程)
实现Tag接口
所有的标签处理器都需要间接或直接的实现这个接口。
下面列出Tag接口定义的方法和常量:
方法名 | 描述 |
int doStartTag() | 当碰到标签起始标记时执行。(<XXX:XXX>) |
int doEndTag() | 当碰到标签结束标记时执行。(</XXX:XXX>) |
Tag getParent() | 获得一个父标签对象 |
void release() | 从内存中释放该标签对象 |
void setPageContext(PageContext) | 设置当前页上下文(page context) |
void setParent(Tag) | 对父标签对象进行设置 |
常量 | 描述 |
EVAL_BODY_INCLUDE | doStartTag()的返回值。指出jsp引擎计算标记体并输出 |
SKIP_BODY | doStartTag()的返回值。指出jsp引擎跳过标记体且不输出 |
EVAL_PAGE | doEndTag()的返回值。指出jsp引擎计算页面剩余部分并输出 |
SKIP_PAGE | doEndTag()的返回值。指出jsp引擎跳过页面剩余部分且不输出 |
setPageContext()方法
setPageContext()方法是一个定制标签声明周期内第一个要被调用的方法。完整写法是:
public void setPageContext(PageContext);
jsp引擎会将jsp页转换时隐含创建的pageContext对象,作为参数,调用setPageContext方法。
通常的做法会将这个参数保存为本标记处理器的参数。
setParent()和getParent()方法
当标签嵌套使用时,外层的标签被成为父标签,内部的被称为子标签。完整的写法是:
public void setParent(Tag);
public Tag getParent();
其中setParent方法对父标签对象进行设置。而getParent方法用以获得父标签对象。
setter方法
当定制标签中包含属性时,在标签处理器中有和javaBean相同的设置机制。即每一个属性XXX,都有对应的setXXX()方法。
这些方法的调用是在setPageContext()和setParent()之后,doStartTag()之前。(就是说所有的属性-即实例变量-必须完全赋值,因为随后的方法可能会调用到它们)
doStartTag()方法
该方法标志着真正的标签处理开始。当前三阶段的方法执行完后,jsp引擎就会调用doStartTag()方法了。完整写法是:
public int doStartTag() throws JspException;
该方法给了标签处理器一个初始化计算和校验属性值合法性的机会。如果初始化失败或属性值不合法,则抛出JspException异常,或其子类,如JspTagException。
初始化计算过后,该方法将决定是否继续对标签体进行计算。作为结果,返回一个整数常量(EVAL_BODY_INCLUDE或SKIP_BODY),用以指示是否跳过标签体的执行。除此之外不返回任何其它值。
doEndTag()方法
执行完doStartTag()方法后,就该执行doEndTag()了。完整写法是:
public int doEndTag() throws JspException;
该方法标志着真正的标签处理结束。同样该方法将决定是否继续执行jsp文件中该标签之后的内容。它也会返回一个整数常量(EVAL_PAGE或SKIP_PAGE),用以指示页面后续内容是否跳过。注意此处的范围是页,并不是转换单位。所以计算不计算全都是针对该页而言。
release()方法
最后,jsp引擎将调用release方法,当标签处理结束,标签处理器对象不再使用时。完整写法是:
public void release();
注意。一个页面内同时有多个相同标签时,jsp引擎会只会为该标签创建一个对象。只有等该页内相同标签全部处理完了。jsp引擎才会调用release()方法,将该标签对象从内存清理掉。
各方法的调用流程如下图: