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 |