Book: JavaServer Pages™, 2nd Edition
Section: Chapter 20.  Developing Custom Tag Libraries



20.1 Tag Extension Basics

A custom action -- actually a tag handler class for a custom action -- is basically a bean, with property setter methods corresponding to the custom action element's attributes. In addition, the tag handler class must implement one of three Java interfaces defined by the JSP specification.

All the interfaces and classes you need to implement a tag handler are defined in the javax.servlet.jsp.tagext package. The three primary interfaces are named Tag, IterationTag, and BodyTag. The Tag interface defines the methods you need to implement for any action. The IterationTag interface extends the Tag interface and adds methods needed for iteration over the action element's body. The BodyTag interface extends the IterationTag interface and adds methods that provide access the content of the action element's body.

There's also a fourth interface named TryCatchFinally; it's a so-called mix-in interface, meaning it can be implemented in addition to any of the three main interfaces. It defines methods that let the tag handler deal with potential exceptions, for instance, those thrown by JSP elements nested in the action element's body.

To make it easier to develop a tag handler, two support classes are defined by the API: TagSupport and BodyTagSupport, as shown in Figure 20-1. The TagSupport class provides default implementations for the methods in both the Tag and the IterationTag interfaces, and BodyTagSupport adds defaults for the BodyTag interface methods.

Figure 20-1. The primary tag extension interfaces and support classes
figs/Jsp2_2001.gif

The reason the specification defines both interfaces and support classes that implement those interfaces is to cover all the bases. If you already have a bean class with functionality you want to access as a custom action, you can specify that it implements the appropriate interface and add the few methods defined by that interface. In practice though, I recommend that you implement your tag handlers as extensions to the support classes. This way you get most of the methods implemented for free, and you can still reuse the existing classes by calling them from the tag handler.

A tag library is a collection of custom actions. For instance, all custom actions used in this book are packaged as one tag library. Besides the tag-handler class files, a tag library must contain a Tag Library Descriptor (TLD) file. This is an XML file that maps all custom action names to the corresponding tag handler classes and describes all attributes supported by each custom action. The class files and the TLD can be packaged in a JAR file to make installation easier. We look at the TLD syntax and packaging details at the end of this chapter.

Before getting into all the intricate details, let's take a brief look at what it takes to develop, deploy, and use a custom action. First, you implement a tag handler class, like the following class:

package com.mycompany;
  
import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
  
public class HelloTag extends TagSupport {
    private String name = "World";
  
    public void setName(String name) {
        this.name = name;
    }
  
    public int doEndTag(  ) {
        try {
            pageContext.getOut(  ).println("Hello " + name);
        }
        catch (IOException e) {} // Ignore it
        return EVAL_PAGE;
    }
}

The tag handler class contains a setter method for an attribute called name. The doEndTag( ) method (defined by the Tag interface) simply writes "Hello" plus the name attribute value to the response.

To compile the class, you must include the JSP API classes in the CLASSPATH environment variable. The classes are distributed with all compliant containers. For Tomcat 4, you find them in the servlet.jar file located in the common/lib directory under the Tomcat installation directory. When you have compiled the tag handler, place the class file in the WEB-INF/classes directory structure for the application so the container can find it.

Next, you create the TLD file. The following is a minimal TLD file for a library with just one custom action element:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
  
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>test</short-name>
  <uri>com.mycompany.mylib</uri>
  
  <tag>
    <name>hello</name>
    <tag-class>com.mycompany.HelloTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
      <name>name</name>
    </attribute>
  </tag>
</taglib>

The TLD maps the custom action name hello to the tag handler class com.mycompany.HelloTag and defines the name attribute. Place the TLD file in the application's WEB-INF/tlds directory, for instance with the filename mylib.tld.

Now you're ready to use the custom action in a JSP page, like this:

<%@ taglib prefix="test" uri="com.mycompany.mylib" %>
<html>
  <body bgcolor="white">
    <test:hello name="Hans" />
  </body>
</html>

When the page is requested, the JSP container uses the taglib directive to find the TLD, and the TLD to figure out which class to execute for the custom action. It then calls all the appropriate methods, resulting in the text "Hello Hans" being added to the response. That's all there's to it for the most simple case. In the remainder of this chapter we'll go through all of this in greater detail.

    [http://safari.oreilly.com/059600317X/jserverpages2-CHP-20-SECT-1]


    Copyright © 2002 O'Reilly & Associates, Inc. All rights reserved.
    1005 Gravenstein Highway North
    Sebastopol, CA 95472