HOME  |    TRAINING  |   FREE TUTORIALS   |   JOBS
Find out more about our new RSS feed.
FREE Tutorial
JAVA SERVER PROGRAMMING TAG EXTENSIONS PART 2 - ANATOMY OF A TAG EXTENSION

CATEGORY
SEARCH OUR OTHER TUTORIALS

DESCRIPTION

Before we return to our simple example, let's cover some basic theory of tag extensions. A number of components are required to implement a tag extension.
Click here to be kept informed of our new Tutorials.


This free tutorial is a sample from the book Professional Java Server Programming J2EE Edition.


The minimal requirement is a tag handler and a tag library descriptor.

  • A tag handler is a Java bean implementing one of two interfaces defined in the javax.servlet.jsp.tagext package, Tag or BodyTag. These interfaces define the lifecycle events relevant to a tag; most importantly, the calls the class implementing the tag will receive when the JSP engine encounters the tag's opening and closing tags.
  • A tag library descriptor, as we have seen, is an XML document containing information about one or more tag extensions.

More complex tags will require an additional class extending the abstract class javax.servlet.jsp.tagext.TagExtraInfo to provide information about scripting variables that are made available to JSPs through the use of tags.

TagExtraInfo subclasses may also perform custom validation of tag attributes. Of course, the classes implementing a tag may require any number of helper classes, which will need to be packaged with the tag for it to be a complete deployable unit.

Before tags can be used in a JSP, the taglib directive must be used to import a tag library and associate the tags it contains with a prefix.

Let's look at each of these requirements in turn.

Tag Handlers

When the JSP engine encounters a tag extension in a JSP at translation time, it parses the tag library descriptor to find the required tag handler class, and generates code to obtain, and interact with, the tag handler. The Tag or BodyTag interfaces, one of which must be implemented by any tag handler, define callbacks that the servlet resulting from the JSP engine's code generation will make to the tag handler instance at runtime.

For performance reasons, JSP engines will not necessarily instantiate a new tag handler instance every time a tag is encountered in a JSP. Instead, they may maintain a pool of tag instances, reusing them where possible. When a tag is encountered in a JSP, the JSP engine will try to find a Tag instance that is not being used, initialize it, use it and release it (but not destroy it), making it available for further use. The programmer has no control over any pooling that may occur. The repeated use model is similar to a servlet lifecycle, but note one very important difference: tag handler implementations don't need to concern themselves with thread safety. The JSP engine will not use an instance of a tag handler to handle a tag unless it is free. This is good news: as with JSP authoring in general, developers need to worry about threading issues less often than when developing servlets.

The javax.servlet.jsp.tagext.Tag Interface

The Tag interface defines a simple interaction between the JSP engine and the tag handler, sufficient for tags that don't need to manipulate their body content. Its core methods are the calls implementing classes will receive when the JSP engine encounters the tag's opening and closing tags, doStartTag() and doEndTag(). Before we look at the method contracts in more detail, a sequence diagram helps to visualize the calls made to the tag handler by the compiled servlet. Assume that the container already has a tag handler instance available, and in the default state:

Let's look at the messages in more detail:

  • The container initializes the tag handler by setting the tag handler's pageContext property, which the tag handler can use to access information available to the JSP currently using it.
  • The container sets the tag handler's parent property. (Parent may be set to null, if the tag is not enclosed in another tag.)
  • Any tag attributes defined by the developer will be set. This is a mapping from the XML attributes of the tag to the corresponding properties of the tag handler bean. For example, in the case of a tag invoked like this: <mytags:test name="John" age="43" />, the container will attempt to call the setName() and setAge() methods on the tag handler. The container will attempt to convert each attribute to the type of the corresponding bean property: for example, the String "43" will be converted to an int in this case. If the type conversion fails, an exception will be thrown and must be handled by the calling JSP page. (From a JSP's point of view, there is no difference between an exception thrown by a tag handler and one thrown by an expression of scriptlet in the page.)
  • Next, the container calls the tag handler's doStartTag() method.
  • The container calls the doEndTag() method.
  • The container calls the release() method. This is not equivalent to a finalizer. Tag handlers differ from page beans in that their lifecycle is entirely independent of that of the JSPs that use them. Tag handlers must support repeated use before destruction, possibly in a number of JSPs. The implementation of the release() method must ensure that any state that may cause conflict in future uses is reset, and that any resources required during the tag's execution are freed.

Lets look at the doStartTag() and doEndTag() methods:

int doStartTag() throws JspException 

Called after the tag has been initialized, when the JSP engine encounters the opening of a tag at run time. Its return value should be one of two constants defined in the Tag interface: EVAL_BODY_INCLUDE, which instructs the JSP engine to evaluate both the tag's body and any child tags it has, or SKIP_BODY, which instructs the JSP engine to ignore the body. This can throw a JspException, as will most of the methods in the tag handler API when an error condition is encountered; how it will be handled will depend on the JSP page using the tag. Most JSP pages will use an error page, so an exception thrown in a tag will abort the rendering of the page.

int doEndTag() throws JspException

doEndTag() is called when the JSP engine encounters the closing tag of an element at run time. Its return value can be EVAL_PAGE or SKIP_PAGE. EVAL_PAGE will cause the JSP engine to evaluate the rest of the page, SKIP_PAGE to terminate evaluation of the page. The SKIP_PAGE return value should be used only with very good reason; using tag handlers to terminate page evaluation is even worse than sprinkling random return statements in Java code, and may be confusing to the reader. A legitimate use might be to terminate page output if it is established that the user has insufficient privileges to view the whole of the page.

There are also a number of methods that relate to tag nesting, initialization, and reuse:

Tag getParent()
void setParent()

The specification also requires methods to expose the parent property. A tag's parent is the tag that directly encloses it in a JSP, or null if there is no enclosing tag. Tag implementations can query their parent at runtime, to obtain context information:

void setPageContext (PageContext pc)

setPageContext() is an initialization method, making the PageContext of the JSP available to the tag.

void release()

release() is a call to the tag handler to release any resources. Examples of this may be closing JDBC connections or open sockets that the handler requires for its function and to clear any state associated with it. The second is an often overlooked task in this context.

The javax.servlet.jsp.tagext.BodyTag Interface

BodyTag extends Tag, adding extra callbacks and other methods allowing the developer to work with the content of the tag.

A sequence diagram displays the interaction between calling JSP and tag handler in the case of a body tag; as you can see, it is somewhat more complex than that of the Tag interface:

The extra steps involve the preservation of the JSP's JSPWriter (messages 5 and 10), and the possibility of repeated calls to the doAfterBody() method, which enables the BodyTag implementation to take control of the tag's execution at runtime.

The more significant methods of the BodyTag interface are listed below.

int doInitBody() throws JspException

Called after the tag has been initialized and doStartTag() has been called. Its return value should be EVAL_BODY_TAG, in which case the tag's body content and any child tags will be evaluated, or SKIP_BODY, in which case the body will be ignored. Watch out that you don't try to return EVAL_BODY_INCLUDE from a BodyTag's doInitBody() or doStartTag() methods. The JSP engine will throw a JspException if it detectes this.

int doAfterBody() throws JspException

doAfterBody() is called each time the tag's body has been processed. The return values are EVAL_BODY_TAG and SKIP_BODY. EVAL_BODY_TAG directs the JSP engine to evaluate the tag's body and any child tags again (resulting in at least one more call to this method), SKIP_BODY, causes processing of the body content to terminate. This can be used to conditionally loop through the tag content.

void setBodyContent(BodyContent bodyContent)

Initialization method to set the class used to manipulate body content.

Continued...


NEXT PAGE



7 RELATED COURSES AVAILABLE
INTRODUCTION TO JAVA PROGRAMMING
The aims of this Java training courses is to understand the role that Java plays on the Internet; describe the be....
JAVA (V1.2): ADVANCED PROGRAMMING
This course teaches the reader to learn, understand and become familiar with the advanced features of Java progra....
INTRODUCTION TO JAVABEANS
To go from the fundamentals of JavaBeans programming to the threshold of Advanced level. Gaining in depth progr....
C++ PROGRAMMING
Object oriented programming is fast becoming the leading software design methodology, with C++ becoming ever more....
C PROGRAMMING
This course is design to provide non-C programmers with the essential skills and knowledge necessary to allow the....
 
1 RELATED JOBS AVAILABLE
JAVA DEVELOPER MANCHESTER
Computer Futures Solutions are seeking a Senior Java Developer for their Manchester based client. You will be joi....
CONTACT US
Saturday 22nd November 2008  © COPYRIGHT 2008 - VISUALSOFT