JSP.5.4 Tag Handlers


A tag handler is a runtime server-side object that is created to help evaluate actions during the execution of a JSP page. A tag handler supports a runtime protocol that facilitates passing information from the JSP page to the handler.

A tag handler is a server-side invisible JavaBeans component, but it implements an additional interface to indicate that it has a richer runtime protocol. There are two interfaces that describe a tag handler: Tag is used for simple tag handlers that are not interested in manipulating their body content (if any); BodyTag is an extension of Tag and gives a tag handler access to its body. The TagSupport and BodyTagSupport classes can be used as base classes when creating new tag handlers.

JSP.5.4.1 Properties

A tag handler has some properties that are set by the JSP container (usually through the JSP page implementation class) using setter methods :

  • The pageContext object for the JSP page where the tag is located; this object can be used to access defined objects.

  • The parent tag handler for the enclosing action.

A tag handler may have additional properties, as any other JavaBean component. These properties will have setters and getter methods, as described in the JavaBeans component specification and used throughout the Java platform.

All attributes of a custom action must be JavaBeans component properties, although some properties may not be exposed as attributes in the tag library descriptor.

Additional translation time information ( TagExtraInfo ) associated with the action indicates the name of the variables it introduces, their types, and their scope. At specific moments (after processing the start tag; after processing the end tag), the JSP container can automatically synchronize the PageContext information with variables in the scripting language so they can be made available directly through the scripting elements.

JSP.5.4.2 Basic Protocol: Tag Interface

This section describes the Tag interface which defines the basic contract for all tag handlers. See Section JSP.5.4.7 for a summary of the life-cycle issues.

A tag handler has some properties that must be initialized before it can be used. It is the responsibility of the JSP container to invoke the appropriate setter methods to initialize these properties. Once properly set, these properties are expected to be persistent, so that if the JSP container ascertains that a property has already been set on a given tag handler instance, it need not set it again. These properties include the properties in the Tag interface as well as other properties.

Once initialized, the doStartTag and doEndTag methods can be invoked on the tag handler. Between these invocations, the tag handler is assumed to hold a state that must be preserved. After the doEndTag invocation, the tag handler is available for further invocations (and it is expected to have retained its properties). Once all invocations on the tag handler are completed, the release method is invoked on it. Once a release method is invoked, all properties are assumed to have been reset to an unspecified value.

Properties

All tag handlers must have the following properties: pageContext and parent . When setting properties, the order is always pageContext and parent . The Tag interface specifies the setter methods for all properties and the getter method for parent.

setPageContext(PageContext)

Sets the pageContext property of a tag handler.

setParent(Tag)

Sets the parent tag for a tag handler.

Tag getParent()

Get the parent tag for a tag handler. This method is used by the findAncestorWithClass static method in TagSupport .

Methods

There are two main action methods and one method for releasing all resources owned by a tag handler.

doStartTag()

Process the start tag of this action. The doStartTag method assumes that the properties pageContext and parent have been set. It also assumes that any properties exposed as attributes have been set too. When this method is invoked, the body has not yet been evaluated.

At the end of this method invocation some scripting variables may be assigned from the pageContext object, as indicated by the optional TagExtraInfo class (at translation time).

This method returns an indication of whether the body of the action should be evaluated ( EVAL_BODY_INCLUDE or EVAL_BODY_TAG ) or not ( SKIP_BODY ). See below for more details.

EVAL_BODY_INCLUDE is not valid if the tag handler implements BodyTag ; EVAL_BODY_TAG is not valid if the tag handler implements Tag and does not implement BodyTag .

This method may throw a JspException .

doEndTag()

Process the end tag of this action. This method will be called after returning from doStartTag . The body of the action may or not have been evaluated, depending on the return value of doStartTag .

At the end of this method invocation some scripting variables may be assigned from the pageContext object, as indicated by the optional TagExtraInfo class (at translation time).

If this method returns EVAL_PAGE , the rest of the page continues to be evaluated. If this method returns SKIP_PAGE , the rest of the page is not evaluated and the request is completed. If this request was forwarded or included from another page (or servlet), only the current page evaluation is completed.

This method may throw a JspException .

release()

Release a tag instance.

Simple Actions with Non-Empty Bodies

If a tag library descriptor maps an action with a non-empty body to a tag handler that implements the Tag interface, the tag handler cannot manipulate this body because there is no mechanism for the tag handler to access that body. To make the situation more explicit, the return value of doStartTag is either SKIP_BODY , EVAL_BODY_INCLUDE or EVAL_BODY_TAG . The meanings are as follows :

  • SKIP_BODY means do not process the body of the action (if it exists).

  • EVAL_BODY_INCLUDE means process the body of the action but do not create a new BodyContent (see below) nor change the value of the out implicit object.

  • EVAL_BODY_TAG means create a new BodyContent , change the value of the out implicit object, and process the body of the action.

A typical use for EVAL_BODY_INCLUDE could be a conditional inclusion action tag. Since the body is to be passed through directly, there is no need for the tag handler to manipulate it, and thus the tag handler need not implement BodyTag .

To help in catching errors, EVAL_BODY_INCLUDE is not valid in a tag handler that implements BodyTag , while EVAL_BODY_TAG is not valid in a tag handler that implements Tag but does not implement BodyTag .

JSP.5.4.3 The TagSupport Base Class

The TagSupport class is a utility class intended to be used as the base class for new tag handlers. The TagSupport class implements the Tag interface and adds additional convenience methods including getter methods for the properties in Tag . TagSupport has one static method that is included to facilitate coordination among cooperating tags.

Tag findAncestorWithClass(Tag, class)

Find the instance of a given class type that is closest to a given instance. This method uses the getParent method from the Tag interface.

The return value of the doStartTag() method is SKIP_BODY . The return value of the doEndTag( ) method is EVAL_PAGE .

JSP.5.4.4 Body Protocol: BodyTag Interface

The BodyTag interface extends Tag with methods to manipulate the body of an action. These methods act on the bodyContent property of a BodyTag instance.

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 Tag , except that the doStartTag method can return either SKIP_BODY or EVAL_BODY_TAG , not EVAL_BODY_INCLUDE . If EVAL_BODY_TAG is returned, then a bodyContent object will be created to capture the body evaluation. This object is obtained by calling the pushBody method of the current pageContext , which additionally has the effect of saving the previous out value. The object is returned through a call to the popBody method of the PageContext class; the call also restores the value of out .

Properties

There is only one additional property: bodyContent

setBodyContent(BodyContent)

Set the bodyContent property. It will be invoked at most once per action invocation. It will be invoked before doInitBody and it will not be invoked if there is no body evaluation.

When setBodyContent is invoked, the value of the implicit object out has already been changed in the pageContext object. The body passed will not have data on it.

Methods

There are two action methods:

doInitBody()

Invoked before the first time the body is to be evaluated. Not invoked in empty tags or in tags returning SKIP_BODY in doStartTag() .

Depending on TagExtraInfo values, the JSP container will resynchronize some variable values after the doInitBody invocation.

This method may throw a JspException .

doAfterBody()

Invoked after every body evaluation. Not invoked in empty tags or in tags returning SKIP_BODY in doStartTag. If doAfterBody returns EVAL_BODY_TAG , a new evaluation of the body will happen (followed by another invocation of doAfterBody ). If doAfterBody returns SKIP_BODY no more body evaluations will occur, the value of out will be restored using the popBody method in pageContext , and then doEndTag will be invoked.

The method re-invocations may lead to different actions because there might have been some changes to shared state, or because of external computation.

Depending on TagExtraInfo values, the JSP container will resynchronize some variable values after every doAfterBody invocation (so a reevaluation of the body will return a different value).

This method may throw a JspException .

JSP.5.4.5 The BodyContent Class

The BodyContent is a subclass of JspWriter that can be used to process body evaluations so they can be retrieved later on. The class has methods to convert its contents into a String , to read its contents, and to clear the contents.

The buffer size of a BodyContent object is "unbounded." A BodyContent object cannot be in autoFlush mode. It is not possible to invoke flush on a BodyContent object, as there is no backing stream. This means that it is not legal to do a jsp:include when out is not bound to the top-level JspWriter .

Instances of this class are created by invoking the pushBody and popBody methods of the PageContext class. A BodyContent is enclosed within another JspWriter (maybe another BodyContent object) following the structure of their associated actions.

The BodyContent type contains four main methods:

clearBody()

This is a version of the clear() method from JspWriter that is guaranteed not to throw exceptions.

getReader()

Get a reader into the contents of this instance.

getString()

As getReader() but returns a String .

writeOut(Writer)

Write out the content of this instance into the provided Writer .

getEnclosingWriter()

Get the JspWriter enclosing t his BodyContent .

JSP.5.4.6 The BodyTagSupport Base Class

The BodyTagSupport class is a utility class intended to be used as the base class for new tag handlers implementing BodyTag . The BodyTagSupport class implements the BodyTag interface and adds additional convenience methods including getter methods for the bodyContent property and methods to get at the previous out JspWriter .

The return value of the doStartTag() method is EVAL_BODY_TAG . The return value of the doEndTag( ) method is EVAL_PAGE . The return value of the doAfterBody() method is SKIP_BODY .

JSP.5.4.7 Life-Cycle Considerations

At execution time the implementation of a JSP page will use an available Tag instance with the appropriate prefix and name that is not being used, initialize it, and then follow the protocol described below. Afterwards, it will release the instance and make it available for further use. This approach reduces the number of instances that are needed at a time.

Initialization is done by setting the properties pageContext and parent , in that order, while release is done by invoking release() .

An Execution Trace

The following example shows the runtime trace for two actions supported by a tag handler implementing BodyTag ; setters are in italics, while actions are not. The inner boxes highlight the portion of the protocol used to interact with the body of the tag. In this example, we are assuming that the second action has the same parent but one different attribute values.

  h.setPageContext(pageContext);   h.setParent(parent);   h.setAttribute1(value1);   h.setAttribute2(value2);...  h.doStartTag()   _______________________________________________                                                     out = pageContext.pushBody()  h.setBodyContent(out)  h.doInitBody()                                  [BODY]                                          h.doAfterBody()                                 ....                                               Body Actions      [BODY]                                          h.doAfterBody()                                 ......                                          out = pageContext.popBody()                 _______________________________________________            h.doEndTag();  h.setAttribute2(value3);  h.doStartTag()   _______________________________________________                                                     out = pageContext.pushBody()  h.setBodyContent(out)  h.doInitBody()                                  [BODY]                                          h.doAfterBody()                                 ....                                               Body Actions      [BODY]                                          h.doAfterBody()                                 ......                                          out = pageContext.popBody()                 _______________________________________________      h.doEndTag();             h.release() 


Java 2 Platform, Enterprise Edition. Platform and Component Specifications
Java 2 Platform, Enterprise Edition: Platform and Component Specifications
ISBN: 0201704560
EAN: 2147483647
Year: 2000
Pages: 399

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net