日期:2014-05-16  浏览次数:20411 次

HF servelt&jsp 定制标记开发 要点总结

1.标记文件使用一个页面来实现标记功能,而标记处理器使用一个java标记处理器类来实现标记功能。

2.标记处理器有两种类型:传统和简单(in jsp 2.0)。

3.建立简单标记处理器时,可以扩展SimpleTagSupport,同时这个类实现了SimpleTag接口。

4.要部署一个标记处理器,必须建立一个tld,使用jstl和其他定制标记库所用的<tag>元素来描述标记。

5.如果使用一个有体的简单标记,要保证这个标记的TLD<tag>没有将<body-content>声明为empty。然后调用getJspBody().invoke()来处理体.

6.SimpleTagSupport类包括SimpleTag接口中所有的方法的实现,另外还提供了3个便利的方法,其中标个包括getJspBody(),可以使用这个方法访问标记体的内容。

7.简单标记声明周期:简单标记绝不会由容器重用,所以每次调用标记时,都会实例化标记处理器,并调用其setJspContext()方法。如果标记本身是从另一个标记中调用的,则会调用setParent()方法。如果调用标记时有属性,对于每个属性会调用一个bean式的设置方法。如果调用标记时有体,则会调用setJspBody()方法。最后,调用doTag()方法,结束时,撤销标记处理器实例。

8.只有调用标记时确实有体,才会调用setJspBody()方法。如果调用标记时没有体,不论是空标记<my:tag/>,还是开始和结束标记<my:tag><my:tag/>之间没有任何内容,都不会调用setJspBody方法。记住,如果标记有体,TLD必须反映出这一点:<body-content>的值不能是“empty”。

9.简单标记的doTag()方法可以设置标记体使用的一个属性,为此先调用getJspContext().setAttribute(),在调用getJspBody().invoke()。

10.doTag方法声明了一个JspException和一个IOException,所以可以直接写至JspWriter,而无需将其包装在一个try/catch块中。

11.通过在循环体调用体getJspBody().invoke(),可以迭代处理简单标记的体。

12.如果标记有一属性,要在tld中使用<attribute>元素声明这个属性,并在标记处理器类中提供一个类似于bean的setter方法。调用时,会在doTag之前调用这个setter方法。

13.getJspBody()方法返回一个JspFragment,它有两个方法:invoke和getJspContext,getJspContext返回一个JspContext,标记处理器可以用这个JspContext访问PageContext API。

14.如果invoke传入null,会把计算的体写至响应输出,不过,如果你想直接访问体内容,可以传入另一个Writer。

15.如果你希望当前页面停止处理,可以跑出一个SkipPageException。如果调用标记的页面包含在另一个页面中,尽管被包含的页面在抛出异常之后就停止处理,但外层页面仍会继续。

?

16.传统标记方法的生命周期返回值:

? BodyTagSupport TagSupport
doSartTag()可能返回的值

SKIP_BODY

EVAL_BODY_INCLUDE

EVAL_BODY_BUFFERED

SKIP_BODY

EVAL_BODY_INCLUDE

实现类的默认返回值

EVAL_BODY_BUFFERED

SKIP_BODY

可以调用的次数 仅一次 仅一次
doAfterBody()可能返回的值

SKIP_BODY

EVAL_BODY_AGAIN

SKIP_BODY

EVAL_BODY_AGAIN

实现类的默认返回值

SKIP_BODY

SKIP_BODY

可以调用的次数 0到多次 0到多次
doEndTag()可能返回的值

SKIP_PAGE

EVAL_PAGE

SKIP_PAGE

EVAL_PAGE

实现类的默认返回值

EVAL_PAGE

EVAL_PAGE

可以调用的次数 仅一次 仅一次
diInitBody()和setBodycontent()在哪些情况下可以调用以及每个标记调用的次数 仅一次,而且仅当doSartTag()返回

EVAL_BODY_BUFFERED

从不调用

?

17.简单标记和传统标记的主要区别:

?

? 简单标记 传统标记
Tag接口 SimpleTag(扩展JspTag)

tag(扩展JspTag)

IterationTag(扩展Tag)

BodyTag(扩展IterationTag)

支持实现类 SimpleTagSupport(实现SimpleTag)

TagSupport(实现IterationTag)

BodyTagSupport(扩展TagSupport实现BodyTag)

可能实现的关键生命周期方法 doTag()

doStartTag

doEndTag

doAfterBody

(对于BodyTag---还有doInitBody()和setBodyContent())

如何写到响应输出 getJspContext().getOut().println(不需要try/catch,因为SimpleTag方法声明了IOException) pageContext.getOut().println(包装在一个try/catch中,因为传统标记方法没有声明IOException)
如何从一个支持实现访问隐式变量和作用域属性 利用getJspContext()方法返回一个JspContext(这通常是一个PageContext) 利用pageContext隐式变量—而不像SimpleTag那样使用一个方法。
如何导致体得到处理 getJspBody().invode(null) 从doStartTag()返回

EVAL_BODY_INCLUDE,或者如果类实现了Bodytag,则返回

EVAL_BODY_BUFFERED

如果让当前页面停止计算 抛出一个SkipPageException 从doEndTag()返回SKIP_PAGE