The life & times of JSP custom tag libraries

First off, I must say that I have used this diagram of the JSP Tag Lifecycle  so many times: http://www.examulator.com/images/iteration_tag.png It has been an invaluable resource.  If some of the events I’m talking about in this post don’t make sense in the big picture, take a look at that diagram.

I recently came across something interesting that I didn’t know before. Sometimes the doAfterBody() event handler does not get invoked within the lifecycle of custom JSP tags that extend TagSupport. Once I figured out when and why, it seems obvious. I just never thought much about it before.

I was creating a custom tag that could optionally take parameters (similar to the way jsp:include tag does). I created a parent tag (aquarium:hasfish) and a child tag (aquarium:param) to be used like this:

<aquarium:hasfish>
   <aquarium:param species=angelfish />
</aquarium:hasfish>

Event handlers for aquarium:hasfish are invoked in this order:

1. doStartTag()
2. doAfterBody()
3. doEndTag()

It is important that the aquarium:param child tag is evaluated before the aquarium:hasfish parent tag does what it needs to do. In other words, since the child tag lives in the body of the parent tag, the body of the tag must be evaluated before the parent tag does anything.

This is how this works:
1. The child tag executes, takes the param value, sets the value on it’s parent tag, and it’s done.
2. the parent tag then does its processing and can use the param value set by the child in step 1.

For the child tag to execute first, the parent tag must wait to use the param until the child tag in the body has executed. Event handlers for BOTH tags together are invoked in this order:
1. doStartTag() for aquarium:hasfish
2. doStartTag() for aquarium:param
3. doEndTag() for aquarium:param
4. doAfterBody() aquarium:hasfish
5. doEndTag() aquarium:hasfish

The param value is not available yet in step 1 when doStartTag() is invoked. The parent must wait until Step 4 doAfterBody() or Step 5 doEndTag() before it can use the param. So it doesn’t matter if you put the parent tag’s code in doAfterBody() or doEndTag(), just pick one, right? Maybe. Read on…

——————————————————————-

If we aren’t interested in passing a parameter, these two examples are basically equivalent….

<%-- no parameter example 1 %-->
<aquarium:hasfish>
</aquarium:hasfish>
<%-- no parameter example 2 %-->
<aquarium:hasfish />

….or are they?

For the most part they are equivalent. Both examples are empty tags without any tag body to evaluate. But when you look at the life cycle of a custom JSP tag that extends TagSupport, there’s one subtle difference.

The second example evaluates the following event handlers in this order:
1. doStartTag() for aquarium:hasfish
2. doEndTag() aquarium:hasfish

What happened to doAfterBody? doAfterBody() doesn’t get invoked in the example 2. Even though there’s an empty body in example 1, there is no body in the example 2. So, doAfterBody() isn’t invoked because there’s no body after which to be invoked.

Makes sense, no body == no after body. Keep in mind if you have custom tags in your application that may or may not have something in the body.

What’s the lesson here?
———————–

1.

<aquarium:hasfish />
/* doAfterBody() not called */
<aquarium:hasfish>
</aquarium:hasfish>
/* doAfterBody() is called */

2. make sure to put the parent tag’s functionality in doEndTag() NOT doAfterBody() if there’s a chance that your tag could be used like

<aquarium:hasfish />

instead of

<aquarium:hasfish>
</aquarium:hasfish>
Advertisements
Posted in code. Tags: . 1 Comment »

One Response to “The life & times of JSP custom tag libraries”

  1. romesh Says:

    this post is awesome and exactly I was looking for. thanks dude!!!!!!!!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: