14.3 Assigning Attributes to Tags
Allowing tags like
<prefix:name attribute1="value1" attribute2="value2" ... />
adds significant flexibility to your tag library. This section explains how to add attribute support to your tags.
The Tag Handler Class
Providing support for attributes is straightforward. Use of an attribute called attribute1 simply results in a call to a method called setAttribute1 in your class that extends TagSupport (or otherwise implements the Tag interface). The attribute value is supplied to the method as a String. Consequently, adding support for an attribute named attribute1 is merely a matter of implementing the following method:
public void setAttribute1(String value1) { doSomethingWith(value1); }
Note that an attribute of attributeName (lowercase a) corresponds to a method called setAttributeName (uppercase A).
One of the most common things to do in the attribute handler is to simply store the attribute in a field that will later be used by doStartTag or a similar method. For example, following is a section of a tag implementation that adds support for the message attribute.
private String message = "Default Message"; public void setMessage(String message) { this.message = message; }
If the tag handler will be accessed from other classes, it is a good idea to provide a getAttributeName method in addition to the setAttributeName method. Only setAttributeName is required, however.
Listing 14.7 shows a subclass of SimplePrimeTag that adds support for the length attribute. When such an attribute is supplied, it results in a call to setLength, which converts the input String to an int and stores it in the len field already used by the doStartTag method in the parent class.
Listing 14.7 PrimeTag.java
package coreservlets.tags; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import java.math.*; import coreservlets.*; /** Generates an N-digit random prime (default N = 50). * Extends SimplePrimeTag, adding a length attribute * to set the size of the prime. The doStartTag * method of the parent class uses the len field * to determine the approximate length of the prime. */ public class PrimeTag extends SimplePrimeTag { public void setLength(String length) { try { len = Integer.parseInt(length); } catch(NumberFormatException nfe) { len = 50; } } }
The Tag Library Descriptor File
Tag attributes must be declared inside the tag element by means of an attribute element. The attribute element has three nested elements that can appear between <attribute> and </attribute>.
name, a required element that defines the case-sensitive attribute name. In this case, I use <name>length</name>
required, a required element that stipulates whether the attribute must always be supplied (true) or is optional (false). In this case, to indicate that length is optional, I use <required>false</required> If you omit the attribute, no call is made to the setAttributeName method. So, be sure to give default values to the fields that the method sets.
rtexprvalue, an optional attribute that indicates whether the attribute value can be a JSP expression like <%= expression %> (true) or whether it must be a fixed string (false). The default value is false, so this element is usually omitted except when you want to allow attributes to have values determined at request time.
Listing 14.8 shows the complete tag element within the tag library descriptor file. In addition to supplying an attribute element to describe the length attribute, the tag element also contains the standard name (prime), tagclass (coreservlets.tags.PrimeTag), info (short description), and bodycontent (EMPTY) elements.
Listing 14.8 csajsp-taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <!-- a tag library descriptor --> <taglib> <!-- after this the default space is "http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd" --> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>csajsp</shortname> <urn></urn> <info> A tag library from Core Servlets and JavaServer Pages, http://www.coreservlets.com/. </info> <!-- Other tag defined earlier... --> <tag> <name>prime</name> <tagclass>coreservlets.tags.PrimeTag</tagclass> <info>Outputs a random N-digit prime.</info> <bodycontent>EMPTY</bodycontent> <attribute> <name>length</name> <required>false</required> </attribute> </tag> </taglib>
The JSP File
Listing 14.9 shows a JSP document that uses the taglib directive to load the tag library descriptor file and to specify a prefix of csajsp. Since the prime tag is defined to permit a length attribute, Listing 14.9 uses
<csajsp:prime length="xxx" />
Remember that custom tags follow XML syntax, which requires attribute values to be enclosed in either single or double quotes. Also, since the length attribute is not required, it is permissible to use
<csajsp:prime />
The tag handler is responsible for using a reasonable default value in such a case.
Figure 143 shows the result of Listing 14.9.
Listing 14.9 PrimeExample.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Some N-Digit Primes</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <H1>Some N-Digit Primes</H1> <%@ taglib uri="csajsp-taglib.tld" prefix="csajsp" %> <UL> <LI>20-digit: <csajsp:prime length="20" /> <LI>40-digit: <csajsp:prime length="40" /> <LI>80-digit: <csajsp:prime length="80" /> <LI>Default (50-digit): <csajsp:prime /> </UL> </BODY> </HTML>
Figure 143 Result of PrimeExample.jsp.