BodyTag (Java EE 5)

Java EE API


javax.servlet.jsp.tagext Interface BodyTag

All Superinterfaces:
IterationTag, JspTag, Tag
All Known Implementing Classes:
BodyTagSupport, UIComponentBodyTag, UIComponentClassicTagBase, UIComponentELTag, UIComponentTag

public interface BodyTag
extends IterationTag

Implements: IterationTag

BodyTag 接口通过定义额外的方法扩展 IterationTag,这些方法允许标记处理程序操作对其正文求值的内容。

由标记处理程序负责操作正文内容。例如,标记处理程序可以取得正文内容,使用 bodyContent.getString 方法将它转换为 String,然后使用它。或者,标记处理程序可以取得正文内容,并使用 bodyContent.writeOut 方法将它写出到其封闭 JspWriter 中。

实现 BodyTag 的标记处理程序可被视为实现了 IterationTag 的标记处理程序,只是 doStartTag 方法可以返回 SKIP_BODY、EVAL_BODY_INCLUDE 或 EVAL_BODY_BUFFERED。

如果返回 EVAL_BODY_INCLUDE,那么将像在 IterationTag 中那样进行求值。

如果返回 EVAL_BODY_BUFFERED,那么将创建 BodyContent 对象(通过 JSP 编译器生成的代码)来捕获正文求值。JSP 编译器生成的代码包含通过调用当前 pageContext 的 pushBody 方法获得的 BodyContent 对象,这会带来保存以前 out 值的额外效果。页面编译器通过调用 PageContext 类的 popBody 方法返回此对象;该调用还恢复 out 的值。

该接口提供了一个带有一个 setter 方法和一个新 action 方法的新属性。

属性

有一个新属性:bodyContent,用于包含 BodyContent 对象,JSP 页面实现对象将正文求值(和重求值,如果适当的话)放入该对象。setter 方法 (setBodyContent) 只在 doStartTag() 返回 EVAL_BODY_BUFFERED 并且相应操作元素不包含空正文时调用。

方法

除了 bodyContent 属性的 setter 方法之外,还有一个新的 action 方法:doInitBody(),该方法就在调用 setBodyContent() 之后、正文求值之前调用。此方法只在 doStartTag() 返回 EVAL_BODY_BUFFERED 时调用。

生命周期

以下的转换图描述了生命周期的详细信息。计算 doStartTag()、setBodyContent()、doInitBody()、BODY、doAfterBody() 期间抛出的异常将中断执行序列,并向上传播到堆栈,除非标记处理程序实现了 TryCatchFinally 接口;有关详细信息,请参见该接口。

BodyTag 的生命周期详细信息转换图

空操作和非空操作

如果 TagLibraryDescriptor 文件指示操作必须总是有一个空元素正文(通过 "empty" 的 <body-content> 条目),则 doStartTag() 方法必须返回 SKIP_BODY。否则,doStartTag() 方法可能返回 SKIP_BODY、EVAL_BODY_INCLUDE 或 EVAL_BODY_BUFFERED。

注意,在 doStartTag() 之后调用哪些方法取决于返回值和自定义操作元素在 JSP 页面中是否为空,而不取决于它在 TLD 中的声明方式。

如果返回 SKIP_BODY,则不对正文求值,并调用 doEndTag()。

如果返回 EVAL_BODY_INCLUDE,并且自定义操作元素不为空,则不调用 setBodyContent(),不调用 doInitBody(),对正文求值并“传递”到当前 out,调用 doAfterBody(),然后在 0 个或更多迭代之后调用 doEndTag()。如果自定义操作元素为空,则仅调用 doStart() 和 doEndTag()。

如果返回 EVAL_BODY_BUFFERED,并且自定义操作元素不为空,则不调用 setBodyContent(),调用 doInitBody(),对正文求值,调用 doAfterBody(),然后在 0 个或更多迭代之后调用 doEndTag()。如果自定义操作元素为空,则仅调用 doStart() 和 doEndTag()。

英文文档:

The BodyTag interface extends IterationTag by defining additional methods that let a tag handler manipulate the content of evaluating its body.

It is the responsibility of the tag handler to manipulate the body content. For example the tag handler may take the body content, convert it into a String using the bodyContent.getString method and then use it. Or the tag handler may take the body content and write it out into its enclosing JspWriter using the bodyContent.writeOut method.

A tag handler that implements BodyTag is treated as one that implements IterationTag, except that the doStartTag method can return SKIP_BODY, EVAL_BODY_INCLUDE or EVAL_BODY_BUFFERED.

If EVAL_BODY_INCLUDE is returned, then evaluation happens as in IterationTag.

If EVAL_BODY_BUFFERED is returned, then a BodyContent object will be created (by code generated by the JSP compiler) to capture the body evaluation. The code generated by the JSP compiler obtains the BodyContent object by calling the pushBody method of the current pageContext, which additionally has the effect of saving the previous out value. The page compiler returns this object by calling the popBody method of the PageContext class; the call also restores the value of out.

The interface provides one new property with a setter method and one new action method.

Properties

There is a new property: bodyContent, to contain the BodyContent object, where the JSP Page implementation object will place the evaluation (and reevaluation, if appropriate) of the body. The setter method (setBodyContent) will only be invoked if doStartTag() returns EVAL_BODY_BUFFERED and the corresponding action element does not have an empty body.

Methods

In addition to the setter method for the bodyContent property, there is a new action method: doInitBody(), which is invoked right after setBodyContent() and before the body evaluation. This method is only invoked if doStartTag() returns EVAL_BODY_BUFFERED.

Lifecycle

Lifecycle details are described by the transition diagram below. Exceptions that are thrown during the computation of doStartTag(), setBodyContent(), doInitBody(), BODY, doAfterBody() interrupt the execution sequence and are propagated up the stack, unless the tag handler implements the TryCatchFinally interface; see that interface for details.

Lifecycle Details Transition Diagram for BodyTag

Empty and Non-Empty Action

If the TagLibraryDescriptor file indicates that the action must always have an empty element body, by an <body-content> entry of "empty", then the doStartTag() method must return SKIP_BODY. Otherwise, the doStartTag() method may return SKIP_BODY, EVAL_BODY_INCLUDE, or EVAL_BODY_BUFFERED.

Note that which methods are invoked after the doStartTag() depends on both the return value and on if the custom action element is empty or not in the JSP page, not how it's declared in the TLD.

If SKIP_BODY is returned the body is not evaluated, and doEndTag() is invoked.

If EVAL_BODY_INCLUDE is returned, and the custom action element is not empty, setBodyContent() is not invoked, doInitBody() is not invoked, the body is evaluated and "passed through" to the current out, doAfterBody() is invoked and then, after zero or more iterations, doEndTag() is invoked. If the custom action element is empty, only doStart() and doEndTag() are invoked.

If EVAL_BODY_BUFFERED is returned, and the custom action element is not empty, setBodyContent() is invoked, doInitBody() is invoked, the body is evaluated, doAfterBody() is invoked, and then, after zero or more iterations, doEndTag() is invoked. If the custom action element is empty, only doStart() and doEndTag() are invoked.


Field Summary
static int
static int
 
Fields inherited from interface javax.servlet.jsp.tagext.IterationTag
 
Fields inherited from interface javax.servlet.jsp.tagext.Tag
 
Method Summary
 void
 void
 
Methods inherited from interface javax.servlet.jsp.tagext.IterationTag
 
Methods inherited from interface javax.servlet.jsp.tagext.Tag
 

Field Detail

英文文档:

EVAL_BODY_TAG

static final int EVAL_BODY_TAG
Deprecated. As of Java JSP API 1.2, use BodyTag.EVAL_BODY_BUFFERED or IterationTag.EVAL_BODY_AGAIN.
Deprecated constant that has the same value as EVAL_BODY_BUFFERED and EVAL_BODY_AGAIN. This name has been marked as deprecated to encourage the use of the two different terms, which are much more descriptive.

See Also:
Constant Field Values


英文文档:

EVAL_BODY_BUFFERED

static final int EVAL_BODY_BUFFERED
Request the creation of new buffer, a BodyContent on which to evaluate the body of this tag. Returned from doStartTag when it implements BodyTag. This is an illegal return value for doStartTag when the class does not implement BodyTag.

See Also:
Constant Field Values

Method Detail

public void setBodyContent(BodyContent b)
设置 bodyContent 属性。此方法由 JSP 页面实现对象调用,每个操作调用最多调用一次。此方法将在 doInitBody 之前调用。不能对空标记或者 doStartTag() 方法返回 SKIP_BODY 或 EVAL_BODY_INCLUDE 的非空标记调用此方法。

在调用 setBodyContent 时,隐式对象 out 的值在 pageContext 对象中已发生更改。传递的 BodyContent 对象上没有数据,但该对象可能已经被以前的某个调用重用(和清除)。

在调用 doEndTag 方法之后,BodyContent 对象才是可用的,并且具有适当内容,在这种情况下,它可以被重用。

b BodyContent
See also doInitBody, doAfterBody

英文文档:

setBodyContent

void setBodyContent(BodyContent b)
Set the bodyContent property. This method is invoked by the JSP page implementation object at most once per action invocation. This method will be invoked before doInitBody. This method will not be invoked for empty tags or for non-empty tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.

When setBodyContent is invoked, the value of the implicit object out has already been changed in the pageContext object. The BodyContent object passed will have not data on it but may have been reused (and cleared) from some previous invocation.

The BodyContent object is available and with the appropriate content until after the invocation of the doEndTag method, at which case it may be reused.

Parameters:
b - the BodyContent
See Also:
doInitBody(), IterationTag.doAfterBody()

public void doInitBody() throws JspException
为正文求值做准备。此方法由 JSP 页面实现对象在 setBodyContent 之后并在第一次对正文求值之前调用。不能对空标记或者 doStartTag() 方法返回 SKIP_BODY 或 EVAL_BODY_INCLUDE 的非空标记调用此方法。

在调用 doInitBody() 之后,JSP 容器将重新同步所有 AT_BEGIN 和 NESTED 变量(由关联的 TagExtraInfo 或 TLD 定义)的值。

ThrowsJspException: 如果在处理此标记时发生错误
See also doAfterBody

英文文档:

doInitBody

void doInitBody()
                throws JspException
Prepare for evaluation of the body. This method is invoked by the JSP page implementation object after setBodyContent and before the first time the body is to be evaluated. This method will not be invoked for empty tags or for non-empty tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.

The JSP container will resynchronize the values of any AT_BEGIN and NESTED variables (defined by the associated TagExtraInfo or TLD) after the invocation of doInitBody().

Throws:
JspException - if an error occurred while processing this tag
See Also:
IterationTag.doAfterBody()


Submit a bug or feature

Copyright 2007 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.

一看就知道只有菜鸟才干这么无知的事啦。

PS : 未经我党受权你也可自由散发此文档。 如有任何错误请自行修正;若因此而造成任何损失请直接找人民主席,请勿与本人联系。谢谢!