通过阅读前三篇文章,已经可以搞定自己的定制标记库了,但是如果不熟悉定制标记运行原理,如果遇到错误可能会不知所措,这篇文章就介绍一下定制标记运行原理。
1.JspTag接口
前面的实例都实现了TagSupport类,并没有直接使用JspTag接口,但实际上标记处理类必须要实现JspTag接口。JspTag接口定义在javax.servlet.jsp.tagext包中,它只是一个标识接口,没有定义任何方法,所有标记处理类必须实现这个接口。
javax.servlet.jsptagext包中还包括IterationTag接口、BodyTag接口、SimpleTag接口、TagSupport类、BodyTagSupport类和simpleTagSupport类,它们之间的继承关系如下:
JspTag接口
|
-----------Tag接口
| |
| ----------IterationTag接口
| |
| ---------------------TagSupport类
| | |
| ----------------BodyTag接口 |
| | |
| ---------BodyTagSupport类
|
-----------SimpleTag接口
|
--------SimpleTagSupport类
Tag接口:
这个接口中定义了编写标记处理类所要实现的基本方法,其中包括一下方法:doStartTag(),doEndTag(),getParent(),release()和setPageContext()方法,其中doStartTag()和doEndTag()方法是最常用的方法。doStartTag()方法在执行到定制标记的开始标记时被调用,doEndTag()方法在执行到定制标记的结束标记时被调用。
在实际编写标记处理类的时候一般不需要直接实现这个接口,通常是继承已经实现了这个接口的TagSupport或者BodyTagSupport类。
IterationTag接口:
这个接口继承自Tag接口,新增加了一个doAfterBody()方法,通常这个方法可以实现对定制标记所包含的内容的循环操作。
doAfterBody()方法只有当doStartTag()方法返回值为EVAL_BODY_INCLUDE时才会被调用。调用doAfterBody()方法,如果返回值是EVAL_BODY_AGAIN,那么将再次运行定制标记所包含的内容并再次调用doAfterBody()方法,直到doAfterBody()方法的返回值为SKIP_BODY,这样就实现对定制标记所包含的操作内容。
TagSupport类:
这个类是我们编写定制标记最常使用的类,实际上它是一个帮助类,可以帮助我们快捷地编写标记处理类,他实现了IterationTag接口。我们编写标记处理类的时候可以直接继承这个类,重写自己所需要的方法,而不需要直接实现IterationTag或者Tag接口。这里使用的设计模式中的缺省适配器模式。
一个继承TagSupport的标记处理类表示这个标记可以显示定制标记所包含的内容,但是不能对所包含的内容进行编辑、改造。如果需要对所包含的内容进行编辑,需要继承BodyTagSupport类
TagSupport类的调用过程如下: