[ Team LiB ] Previous Section Next Section

Processing Body Content with a Custom Tag

Processing body text is a little more involved and requires a specialized tag interface. A tag that processes its body text must implement the BodyTag interface and usually extends BodyTagSupport.

Because the BodyTag interface extends the Tag interface, it includes the doStartTag and doEndTag methods. A tag implementing the BodyTag interface might still return SKIP_BODY from the doStartTag method to indicate that the JSP engine should not evaluate the text between the beginning and end of the tag. A body tag may also return EVAL_BODY_INCLUDE to include its body text or EVAL_BODY_BUFFERED if it wants to examine or manipulate the body content.

Body tags have a complex protocol for operating on body text. If the doStartTag method returns EVAL_BODY_BUFFERED, the JSP engine calls the doInitBody method in the custom tag before it starts evaluating the body text. There is no return value for doInitBody as it is intended for you to perform initialization in this method. After the JSP engine evaluates the body content, it calls doAfterBody in the custom tag. The custom tag can access the current body content by calling getBodyContent until the end of the invocation of doEndTag. If doAfterBody returns EVAL_BODY_AGAIN, the JSP engine reevaluates the current body content and calls doAfterBody again. The JSP engine finally accepts the content after doAfterBody returns SKIP_BODY.

Avoid Infinite Loops

graphics/watchout_icon.gif

Make sure you always have a case where your doAfterBody method returns SKIP_BODY. If you return only EVAL_BODY_AGAIN, the JSP engine will get stuck in an infinite loop calling your doAfterBody method over and over.


Let's take a look at a very minimal body tag. Listing 16.8 shows a body tag that prints its body text to the response (in other words, it shows the text between its begin and end tags as if the tags weren't there).

Listing 16.8 Source Code for TestBodyTag.java
package examples.taglibs;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;

public class TestBodyTag extends BodyTagSupport
{
    public int doStartTag()
        throws JspException
    {
        return EVAL_BODY_BUFFERED;
    }

    public int doEndTag()
    {
        return EVAL_PAGE;
    }

    public void doInitTag()
    {
    }

    public int doAfterBody()
        throws JspException
    {
// Get the current body content
        BodyContent body = getBodyContent();

        try
        {
// Ask the body content to write itself out to the response.
            body.writeOut(body.getEnclosingWriter());
        }
        catch (IOException exc)
        {
            throw new JspException(exc.toString());
        }
// Tell the JSP engine that the body content has been evaluated.
        return SKIP_BODY;
    }
}

Having Trouble with the Example?

graphics/bytheway_icon.gif

If you are having trouble getting a body tag to work, see the "Q&A" section at the end of this hour.


In Listing 16.8, you see that you can write the body content into the response by calling body.writeOut(body.getEnclosingWriter()). The body.writeOut method writes the contents of the body to any Writer object. The getEnclosingWriter method returns the writer for the section of the response in which this body tag is contained. You can use body.getReader to get a Reader object that lets you read the contents of the body, or you can just call body.getString to return the body content as a string. In fact, an alternative way to write out the contents of a body is


body.getEnclosingWriter().println(body.getString());

Usually, you'll use the string representation or Reader to inspect or modify the tags content.

    [ Team LiB ] Previous Section Next Section