|
|
![]() |
|
|
How to Create Custom JSP Tags by Richard Shaler [The code for this article is available for download.]
JavaServer Pages are meant to create dynamic Web page content. However, in your quest to create dynamic content, you may clutter your JSP with too much Java code, or at least more Java code than your Web page design and maintenance staff would like to deal with. There is a solution to this problem that was introduced in the JSP 1.1 specification. Custom tags let you replace Java code in your JSPs with simple-to-use, XML-formatted statements. In some of my previous articles, I showed you how to reduce the amount of Java code in your JSPs by using JavaBeans. To link a JSP to a JavaBean, you use a JSP action element: <jsp:usebean . . .> Another technique for reducing the amount of Java code in a JSP is to use custom tags. A custom tag is really considered a JSP action element, because it uses the same syntax. They perform some type of action that you define. The benefit of custom tags is that you can provide powerful features in your JSP without exposing the page to a lot of Java code. Custom tags facilitate the separation of business logic from presentation logic. The Java code that actually does the work of the custom tag is contained in a tag library that you create. The tag library contains what some refer to as "tag handlers," which are simply Java programs that use some special servlet tag classes. The JSP developer doesn't have to deal with the code, but instead deals with an easy-to-understand XML-formatted tag statement. The Custom Tag Library Architecture To help you understand how custom tags work, examine the illustration in Figure 1.
As you can see from the illustration, there are three major components used by custom tags: the JSP, the tag library descriptor (or TLD), and the tag library. A deployment descriptor file can be used to help you define your application--including the location of your tag library descriptor file--to the Web server. The JSP Now I'll describe how you link your JSP to the required custom tag library components (the TLD and the tag library), as well as describe the components in more detail. The taglib Directive For your JSP to access custom tags, it must know where the tag library is and it must specify the tag prefix you have assigned to your tag library. Both pieces of information are provided through a special taglib directive. The directive format is the following: <% @ taglib uri="<tag_library_descriptor_or_tag_libary_package>" prefix="<tag_prefix>" %> The uri value is a reference to your tag library descriptor file (you'll learn more about this later) or to a JAR file (if you package your tag library into a JAR file). The prefix is the name that is associated with all tags defined in the tag library. It is normally an abbreviated or short name that represents what the tag library tags do. For example, you might use a prefix of ut to represent a group of utility tags. The Custom Tag The custom tag is similar to the JSP action tag. As mentioned previously, you use a JSP action element to link a JavaBean to a JSP. The following JSP action element links a JavaBean named CustomerBean to the JSP.
<jsp:usebean id="Customer" class="com.itechtutor.CustomerBean">
</jsp:usebean>
or <jsp:usebean id="Customer" class="com.itechtutor.CustomerBean" /> Here, the tag library prefix is jsp and the action is usebean. This JSP action element contains two attributes: id, which gives the JavaBean an identifier that can be used throughout the JSP, and class, which references the JavaBean class. Once the JavaBean is linked, you can access its properties with the setProperty and getProperty action tags. For example, you can set and retrieve the customer name of the above CustomerBean with the following action elements: <jsp:setProperty name="Customer" property="custName" value="George Bush" /> <jsp:getProperty name="Customer" property="custName" /> Custom tags are specified exactly the same as the above tags. The only difference is that you define them. Here is an example of a custom tag I use later in my sample. <ut:repeat count="5" > <%= new java.util.Date() %> </ut:repeat> Here, the tag library prefix is ut and the tag contains one attribute: count. This custom tag is a little more complex because it contains a body--the value submitted between the ut begin and end tags. The body of this tag statement contains the date value returned by the java.util.Data() expression. The Tag Library Even though custom tags allow you to eliminate Java code from your JSP, they don't eliminate the need to create Java code. You still must create Java classes to carry out the work for the custom tag. These classes are not a lot different from any other Java class, except that they use a special servlet package, called tagext, that contains special tag handling methods such as Tag, TagInfo, TagSupport, and BodyTagSupport. The Tag Library Descriptor Before you can exploit a tag library, you must describe the library: the tags contained within it, the tag attributes (if any), and the Java classes that do the work for the tag. You describe a tag library with a tag library descriptor document. Think of a TLD document as containing the metadata for a tag library. The TLD document uses standard XML statements to define the tag library. A Sample Custom Tag To help get you started in developing your own custom tags, I present a custom tag sample I created, called repeat. This tag provides a looping mechanism to a JSP that displays the body of the tag a specified number of times. In this case, the body of the tag contains the current date and time. Figure 2 illustrates the output of a JSP that uses the custom tag.
This JSP's name is TestRepeatTag. Look at the source code and notice how simple it was for me to set up a looping mechanism. There's no Java code, just a few simple XML statements. Examine the entire custom tag specifications below: <ut:repeat count="5"> <%= new java.util.Date() %> <br> </ut:repeat> I'm using the count attribute to pass the number of times this tag is to repeat--in this case 5 times. In between the opening and closing tags, I'm supplying a JSP expression that resolves to the current date. I'm also placing a break tag (<br>) after the expression, so each iteration of the tag will cause the date to appear on a different line. As mentioned previously, the values you supply between the opening and closing tags are known as the body. Of course, behind the scenes there is some Java code. The Java code for the repeat tag is contained in a Java class called RepeatTag. The important thing to understand about tag handler classes is that there are a number of methods that are automatically called when a JSP custom tag is processed. In the RepeatTag class, there are four methods:
The opening tag of a custom tag causes the doStartTag() method to execute, and it executes only once for each use of the custom tag. The doStartTag() starts by checking to see if the currentCount variable is less than maxCount. If true, it returns the EVAL_BODY_TAG constant; if false, it returns the SKIP_BODY constant. Returning EVAL_BODY_TAG causes everything between the start and end tag (the body) to be processed; returning SKIP_BODY causes everything between the start and end tags to be ignored. The EVAL_BODY_TAG is unique, in that it automatically causes the doAfterBody() method to execute. So the doAfterBody() method executes whenever the EVAL_BODY_TAG is returned. In the RepeatTag class, the doAfterBody() starts by incrementing the currentCount variable. If currentCount is less than value of maxCount, EVAL_BODY_TAG is returned, causing the doAfterBody() method to run again. This is what causes the looping. The doAfterBody() repeatedly calls itself (by returning EVAL_BODY_TAG) until the currentCounter value reaches the maxCount value. The closing tag causes the doEndTag() method to execute. Each time the body of the custom tag is processed, the closing tag is encountered. This means that for each iteration of the doAfterBody() method, the doEndTag() is also processed. In RepeatTag, the doEndTag() writes the value of the custom tag body to the browser (in this case, the body value is the current date and time). The code required to write to the browser is a little convoluted, and I won't get into why. Just know that you can copy this code into your own tag handler program to cause your custom tag body to be written to the browser. Also, know that there are other methods for writing custom tag body values. A tag library is not usable until you create a tag library descriptor document for it. For the sample application, I created the iTechTutorUtilTags document to describe the sample tag library. Because the TLD specifications use XML syntax, they are intuitive.
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>ut</shortname>
<info>iTechTutor Utility Tag Library</info>
<tag>
<name>repeat</name>
<tagclass>com.itechtutor.utilitytags.RepeatTag</tagclass>
<bodycontent>JSP</bodycontent>
<info>Provides looping</info>
<attribute>
<name>count</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
Notice that the outermost tag for a tag library is <taglib>. Within <taglib> you define general information about the library and the tags the library supports. The <shortname> tag is where you specify the name of your tag library, which is also the prefix you use in any JSP that uses the tag library. This tag library contains only one tag: repeat. You can see its definition within <tag> and </tag>. Notice the repeat uses a single attribute named count, and that it is a required attribute. Most production tag libraries would contain multiple tags, and it's likely that the tags would contain multiple attributes. Tag Library Deployment Here, I used the simplest approach to making the custom tag library available to my servlet engine (in this case, Tomcat), so my application could exploit it. I placed the TLD file in the same directory as the JSP, and I placed the tag handler in a directory path that agreed with its package name (com.itechtutor.utilitytags). Here is how the components of this application are stored, including the structure of its directories:
webapps
myApp
jsp
TestRepeatTag.jsp
iTechTutorUtilTags.tld
WEB-INF
classes
com
itechtutor
utilitytags
RepeatTag.class
RepeatTag.java
In a production environment, you would want to package the tag library and TLD into a JAR file for easier deployment. But explaining how to do that is beyond the scope of this article. Tag, You're It JSPs expose the power of the Java development environment to your Web pages. But the code required to exploit that power isn't necessarily something you want to expose to the people who design and maintain your Web pages. Fortunately, now that you know how to create custom tags, you have the ability to essentially eliminate Java code from your JSPs. Your JSPs can still offer all the power of the Java development environment, but with an interface that most any Web page developer could easily understand and use. Related Articles How to Interact Directly with JavaBeans from JSPs Simplify JSP Applications with JavaBeans, Part 2 Simplify JSP Applications with JavaBeans, Part 1
|
Editors
Contact the Editors |
|
Last Updated: 9/12/02 Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |