Package javax.servlet.jsp.tagext

Classes and interfaces for the definition of JavaServer Pages Tag Libraries.

See:
          Description

Interface Summary
BodyTag The BodyTag interface extends Tag by defining additional methods that let a Tag handler access its body.
Tag The Tag interface defines the basic protocol between a Tag handler and JSP page implementation class.
 

Class Summary
BodyContent A JspWriter subclass that can be used to process body evaluations so they can re-extracted later on.
BodyTagSupport Actions in a Tag Library are defined through subclasses of Tag.
TagAttributeInfo Information on Tag Attributes; this class is instantiated from the Tag Library Descriptor file (TLD).
TagData Tag instance attribute(s)/value(s); often this data is fully static in the case where none of the attributes have runtime expresssions as their values.
TagExtraInfo Extra Tag Information for a Custom Tag; this class is mentioned in the Tag Library Descriptor file (TLD).
TagInfo Tag information for a tag in a Tag Library; this class is instantiated from the Tag Library Descriptor file (TLD).
TagLibraryInfo Information on the Tag Library; this class is instantiated from the Tag Library Descriptor file (TLD).
TagSupport Actions in a Tag Library are defined through subclasses of Tag.
VariableInfo Information on the scripting variables that are created/modified by a tag (at run-time); this information is provided by TagExtraInfo classes and it is used by the translation phase of JSP.
 

Package javax.servlet.jsp.tagext Description

Classes and interfaces for the definition of JavaServer Pages Tag Libraries.

The JavaServer Pages(tm) (JSP) 1.1 specification provides a portable mechanism for the description of tag libraries.

A JSP tab library contains

The JSP 1.1 specification and the reference implementation both contain simple and moderately complex examples of actions defined using this mechanism. These are available at JSP's web site, at http://java.sun.com/products/jsp. Some readers may want to consult those to get a quick feel for how the mechanisms work together.

Tag Extension Basics

The basic principles of a tag extension are the tag library descriptor file (TLD) and the tag handlers.

The Tag Library Descriptor

The Tag Library Descriptor (TLD) is a file that describes a tag library. It is an XML document that conforms to the DTD described in the JSP 1.1 specification. The TLD for a tag library is used by a JSP engine to execute pages that include taglib directives refering to that tag library. The TLD is also used by JSP authoring tools that will generate JSP pages that use the library so described, and by authors who do the same manually.

The TLD includes documentation strings on the library as a whole and on its individual tags, version information on the required JSP engine and on the tag library, and information on each of the actions defined in the tag library.

Each tag in the library is described by giving its name, the class for its tag handler, optional information on scripting variables introduced by this tag, and information on all the attributes of the tag. Each valid attribute is mentioned explicitly, with indication on wheher it is mandatory or not, whether it can accept request-time expressions, and additional information.

See the DTD or the JSP 1.1 specification for more details.

Tag Handler

A Tag Handler is a run-time server-side object that is created to help evaluate tags during the execution of a JSP page. A Tag handler is an invisible server-side JavaBeans component that supports an additional protocol for better integration within a JSP page. Tag handlers can be used by JSP authors and authoring tools to simplify writing JSP pages.

An action Tag (in JSP 1.1 there is no mechanism for defining custom directives) has a start tag, possibly a body, and an end tag. A prototypical example is of the form:




<x:foo att="myObject" >

  BODY

</x:foo/>



An empty tag has no body, in which case the start and end tags can be combined as follows:



<x:foo att="myObject" />



The Tag handler protocol is described by the Tag interface, and the BodyTag interface.

The Tag Interface

A Tag handler that does not want to process its body can implement just the Tag interface. There are several reasons why a tag handler will not want to process its body: because it has none (there is a mechanism in the TLD to require the JSP parser to verify that), or because the body is just to be "passed through".

The Tag interface includes methods to provide page context information to the Tag Handler instance, methods to handle the life-cycle of tag handlers, and two main methods for performing actions on a tag: Tag.doStartTag() and Tag.doEndTag(). The method doStartTag() is invoked when encountering the start tag and its return value indicates whether the body (if there is any) should be skipped, or evaluated and passed through to the current response stream. The method doEndTag() is invoked when encountering the end tag; its return value indicates whether the rest of the page should continue to be evaluated or not.

These two methods can access the tag attributes and their values and can also access the PageContext object of the page.

The TagSupport class is a base class that can be used when implementing the Tag interface. See Tag and TagSupport for more information.

Tag Extension Details

The BodyTag Interface

If a Tag handler wants to have access to the content of its body then it must implement the BodyTag interface. This interface extends Tag, provides three additional methods BodyTag.setBodyContent(BodyContent), BodyTag.doInitBody() and BodyTag.doAfterBody() and refers to an object of type BodyContent.

A BodyContent is a subclass of JspWriter that has a few additional methods to convert its contents into a String, insert the contents into another JspWriter, to get a Reader into its contents, and to clear the contents. Its semantics also assure that buffer size will never be exceeded.

The JSP page implementation will create a BodyContent if the doStartTag() method returns a EVAL_BODY_TAG. This object will be passed to doInitBody(); then the body of the tag will be evaluated, and during that evaluation out will be bound to the BodyContent just passed to the BodyTag handler. Then doAfterBody() will be evaluated. If that method returns SKIP_BODY, no more evaluations of the body will be done; if the method returns EVAL_BODY_TAG, then the body will be evaluated, and doAfterBody() will be invoked again.

A common use of the BodyContent is to extract its contents into a String and then use the String as a value for some operation. Another common use is to take its contents and push it into the out Stream that was valid when the start tag was encountered (that is available from the PageContext object passed to the handler in setPageContext).

See the javadoc documentation for more details.

Tag mapping, Tag name and Tag life cycle

A taglib directive introduces a tag library and associates a prefix to it. The TLD associated with the library associates Tag handler classes (plus other information) with tag names. This information is used to associate a Tag class, a prefix, and a name with each custom action element appearing in a JSP page.

At execution time the implementation of a JSP page will use an available Tag instance with the appropriate prefix, name, PageContext, parent, and TagData and then follow the protocol described below. The implementation guarantees that all tag handler instances are initialized and all are released, but the implementation can assume that previous settings are preserved by a tag handler, to reduce run-time costs. See the JSP 1.1 specification for more details.

A Run-Time Trace

The following figure shows the run-time trace for a "complex" Tag instance; methods invoked by the JSP page code that almost never redefined by a specific Tag handler are in blue, and the portion of the protocol used to interact with the body of the element is shown separatedly.




h.setPageContext(pageContext);

h.setParent(parent);

h.setTagData(tagData);



h.doStartTag()

___________



out = pageContext.pushBody()

h.setBodyContent(out)





h.doInitBody()

[BODY]

h.doAfterBody()

.....

[BODY]

h.doAfterBody()

......



out = pageContext.popBody()



___________



h.doEndTag()



h.release()



PageContext

Often two actions in a JSP page will want to cooperate, perhaps by one action creating some server-side object that needs to be access by another. One mechanism for doing this is by giving the object a name within the JSP page; the first action will create the object and associate the name to it while the second action will use the name to retrieve the object.

For example, in the following JSP fragment the foo action might create a server-side object and give it the name "myObject". Then the bar action might access that server-side object and take some action.




<x:foo id="myObject" />

<x:bar ref="myObjet" />



In a JSP implementation, the mapping "name"->value is kept by the implicit object pageContext. This object is passed around through the Tag handler instances so it can be used to communicate information: all it is needed is to know the name under which the information is stored into the pageContext.

The Runtime Stack

An alternative to explicit communication of information through a named object is implicit coordination based on syntactic scoping.

For example, in the following JSP fragment the foo action might create a server-side object; later the nested bar action might access that server-side object. The object is not named within the pageContext: it is found because the specific foo element is the closest enclosing instance of a known element type.




<foo>

   <bar/>

</foo>



This functionality is supported through the TagSupport.findAncestorWithClass(Tag, Class), which uses a reference to parent tag kept by each Tag instance, which effectively provides a run-time execution stack.

Scripting Variables

JSP supports scripting variables that can be declared within a scriptlet and can be used in another. JSP actions also can be used to define scripting variables so they can used in scripting elements, or in other actions. This is very useful in some cases; for example, the jsp:useBean standard action may define an object which can later be used through a scripting variable.

Since the logic that decides whether an action instance will define a scripting variable may be quite complex, this information is not encoded in the Tag Library Descriptor directly; rather, the name of a TagExtraInfo class is given in the TLD. The getVariableInfo method of this class is used at translation time to obtain information on each variable that will be created at request time when this action is executed. The method is passed a TagData instance that contains the translation-time attribute values.

Refer to TagExtraInfo and to the JSP 1.1 specification for more details.

Validation

The TLD file contains several pieces of information that is used to do validation at translation-time. Additional translation-time validation can be done using the TagExtraInfo class, namely the isValid() method. As in getVariableInfo method, the isValid() method is invoked at translation-time and has a TagData instance as its value.

In some cases, additional request-time validation will be done dynamically within the methods in the Tag instance. If an error is discovered, an instance of JspTagException can be thrown. If uncaught, this object will invoke the errorpage mechanism of JSP.

Related Documentation

See Chapters 5 and 7, and Appendices A, and B of the JavaServer Pages 1.1 specification documents for more details.

For overviews, tutorials, examples, guides, tool support, and other documentation, please see the JSP home page and the Java Servlet home page