JavaEnterprise JavaUse the BodyTagSupport Class to Add More Flexibility to JSP Pages

Use the BodyTagSupport Class to Add More Flexibility to JSP Pages

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

JSP tag libraries allow the developer to associate code to XML-like tags. Methods such as doStartTag() or doEndTag() are called as the JSP engine processes the page. There are times, however, when the “body” of the tag has some significance and needs to be captured or manipulated by the application.

Piroz Mohseni

For example, we may have a “headline” tag that delimits some text to be used as the header of an article. If the page needs to capture the headline itself and syndicate it, store in a database or change the way it is presented, then it needs to access the body of the tag. The BodyTagSupport class provides this capability. It is a subclass of TagSupport with additional methods for interacting with the body content. It does so by implementing the interface BodyTag.

This interface consists of three methods. The doInitBody() method prepares for evaluation of the body content. The doAfterBody() performs any actions needed after the evaluation of the body content. The setBodyContent() method is used to set the bodyContent property.

The BodyTagSupport class provides a method called getBodyContent() which is what you use to get a BodyContent object. Access to the tag body provides additional flexibility to a JSP programmer. Users familiar with HTML can insert specific data inside the JSP page (using custom tags). By accessing the tag body, your custom tags can extract and transform that data into a suitable format. For example, raw numerical data can be transformed into an HTML table. By providing various attributes for the tag, you can further customize the behavior of the tag.

The following listing shows a tag that takes numbers delimited by a comma and displays them in an HTML table. Each row consists of multiple numbers separated by a comma. A semicolon indicates end of a row. Using the StringTokenizer class, the doEndTag() method parses the numbers (which are inside the body of the tag) and produces an HTML table.

package stag;

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

public class STag extends BodyTagSupport 
{
    protected String elemSep =  ",";
    protected String lineSep = ";";
 
    public int doEndTag() throws JspException 
    {
       String bodyText = bodyContent.getString();
       
       try {
       	pageContext.getOut().print(bodyText);
       }
       catch (Exception e) {
       	throw new JspTagException(e.getMessage());
       }
       
       StringBuffer tableOut = new StringBuffer(); 
       StringTokenizer bodyTk = new StringTokenizer(bodyText, lineSep, false);
       
       tableOut.append("<TABLE>");
       while (bodyTk.hasMoreTokens())
       {
           String str = (String)bodyTk.nextToken();
           StringTokenizer token = new StringTokenizer(str, elemSep, false);
           tableOut.append("<TR>");
           while(token.hasMoreTokens())
           {
                tableOut.append("<TD>"); 
                tableOut.append((String)token.nextToken()); 
                tableOut.append("</TD>"); 
           }
           tableOut.append("</TR>");
       } 
      tableOut.append("</TABLE>");
       
      try {
       	pageContext.getOut().print(tableOut);
       }
       catch (Exception e) {
       	throw new JspTagException(e.getMessage());
       } 
       return EVAL_PAGE;        
    }

    public void release() 
    {
       elemSep = ",";
       lineSep = ";";
    }

}

Here is a JSP page using this tag:

<%@ taglib uri="/stag" prefix="tbl" %>
<html>
<body>
<tbl:stag>
1,2,3,4;
2,12,3,9;
</tbl:stag>
</body>
</html>

The output would be:

<html>
<body>
<TABLE>
<TR><TD>1</TD><TD>2</TD><TD>3</TD><TD>4</TD></TR>
<TR><TD>2</TD><TD>12</TD><TD>3</TD><TD>9</TD></TR>
</TABLE>
</body>
</html>

There are some drawbacks to this approach as well. The custom tag code must be prepared to handle any data entered by the user and perform error handling if the data is not correct. It is recommended that this approach be used in controlled situations where the number of JSP page authors is limited and they can be trained on the specifics of using the custom tags.

Another useful technique is to capture the body using the bodyContent.getString() method and then share it to other elements of the JSP page. This can be done via the setAttribute() method of javax.servlet.jsp.PageContext. By setting a global attribute value to the body content of a custom tag, you can make that content available to other tags in the page. This is a technique that can prove to be valuable when various tags from different libraries need to communicate and share information. Obviously, by introducing this coupling, the custom tags lose their independence, but you gain extra functionality.

Have you written a useful class and would like it to be featured as “Class of the Month?” Contact me at mohseni@bita-tech.com.

About the Author

Piroz Mohseni is president of Bita Technologies, focusing on business improvement through the effective use of technology. His areas of interest include enterprise Java, XML, and e-commerce applications.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories