IBM Skip to main content
Search for:   within 
      Search help  
     IBM home  |  Products & services  |  Support & downloads   |  My account

developerWorks > Java technology
developerWorks
JSP best practices: Intro to taglibs
68 KBe-mail it!
Contents:
Why taglibs?
From scriptlets to tags
Implementing behavior
Creating a TLD
Wrapping up
Resources
About the author
Rate this article
Related content:
JSP best practices series
Take control of your JSP pages with custom tags
JSP taglibs: Better usability by design
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
Convert scriptlets to custom tags for better JSP code

Level: Introductory

Brett McLaughlin (mailto:brett@oreilly.com?cc=&subject=Intro to taglibs)
Author, O'Reilly and Associates
23 July 2003

Column iconScriptlets are good for fast-and-dirty coding, but in the long run you need a less cluttered solution for your JSP pages. In this installment of JSP best practices, Brett McLaughlin shows you how to convert a scriptlet into a JSP custom tag, add it to a custom tag library, and begin using it in your JSP development.

In the last installment of JSP best practices, you learned a scriptlet-based technique for adding last-modification time stamps to your JavaServer Pages (JSP) files. Unfortunately, scriptlets introduce more long-term complexity to your pages than they offer in terms of short-term benefit. They interweave all sorts of HTML with Java code, which makes debugging and authoring tricky. They aren't reusable, which often leads developers to cut-and-paste between JSP pages, which in turn leads to multiple versions of the same piece of code. And they make error reporting difficult, since JSP pages have no clean-cut way to spit out script errors.

So this time we'll devise a better solution. In this installment, you'll learn the basics of converting a scriptlet to a custom tag and setting it up for use in your JSP development projects.

Why taglibs?
A tag library is a library of tags that can be used in your JSP pages. JSP containers comes with a small, default tag library. A custom tag library is a library that has been put together for a specific use or purpose. Developers working together in a team might create very specific custom tag libraries for individual projects, as well as a more general one for ongoing use.

JSP tags replace scriptlets and alleviate all the headaches that come with them. For example, you might see tags like this:

<store:shoppingCart id="1097629"/>

or this:

<tools:usageGraph />

Each tag contains a reference to a Java class but keeps that code exactly where it belongs: out of the page and in a compiled class file.

From scriptlets to tags
The first step in creating a custom tag is to decide how you want it to be used, what you will call it, and what (if any) attributes it should allow or require. In the case of the time-stamp tag, our needs are pretty simple: we want a simple tag that outputs the last-modification date of a page.

Because no attributes are required the tag can look something like

<site-utils:lastModified />

The name and prefix of the tag are the same: site-utils. The element's content is empty, meaning no child elements are allowed within it. After you've defined the tag, the next step is to implement its behavior.

Implementing behavior
The first step to implementing tag behavior is to move our scriptlet code from the previous installment into a Java class (LastModifiedTag), as shown in Listing 1:

Listing 1. Creating a time-stamp tag

package com.newInstance.site.tags;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.TagSupport;

public class LastModifiedTag extends TagSupport {

    public int doEndTag() {
      try {
        HttpServletRequest request =
(HttpServletRequest)pageContext.getRequest();
        String path = pageContext.getServletContext().getRealPath(
          request.getServletPath());
        File file = new File(path);

        DateFormat formatter = DateFormat.getDateInstance(
          DateFormat.LONG);

        pageContext.getOut().println(
          formatter.format(new Date(file.lastModified())));
      } catch (IOException ignored) { }
      return EVAL_PAGE;
    }
}

The code in this method should look familiar; it's essentially the same time stamp code we worked with in the previous installment. Because no user input is required, and the tag has no attributes or nested content, the only new method we need to worry about is doEndTag(), which is where the tag can output content (in this case the last-modification date) to a JSP page.

Other changes in Listing 1 have to do with the code being a JSP tag rather than a scriptlet operating within a page. All JSP tags, for example, should extend the JSP class javax.servlet.jsp.tagext.TagSupport, which provides the basic framework for JSP tags. You might also notice that the tag returns EVAL_PAGE. EVAL_PAGE is a pre-defined integer constant that instructs the container to process the rest of the page. Another option would be to use SKIP_PAGE, which aborts processing for the rest of the page. You need only to use SKIP_PAGE if you are passing off control to another page, such as when you forward or redirect the user. The rest of the details are specific to the time stamp itself.

Next, we compile this class and place the LastModifiedTag.class file in a WEB-INF/classes directory, within its proper path hierarchy. This path should match the package name of the tag, replacing the dots (.) in the package name with slashes (/). In our case, the directory path is the base (WEB-INF/classes) plus the hierarchy, com/newInstance/site/tags. If you had a tag called foo.bar.tag.MyTag, it would go in WEB-INF/classes/foo/bar/tag. This path hierarchy ensures that the Web container can locate the class whenever it is called upon to load the tag.

Creating a TLD
The next step is to create a tag library descriptor (TLD) file. The TLD describes your tag library to the container and any JSP pages that may use it. Listing 2 shows a fairly standard TLD, containing only one tag. The length and complexity of your TLD file will grow as you add more tags to the library.

Listing 2. A tag library descriptor

<?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>site-utils</short-name>
    <uri>http://www.newInstance.com/taglibs/site-utils</uri>

    <tag>
      <name>lastModified</name>
      <tag-class>com.newInstance.site.tags.LastModifiedTag</tag-class>
      <body-content>empty</body-content>
    </tag>
</taglib>

The information at the top of the TLD file applies to the entire tag library. In this case, I've supplied a version (useful for tracking which version of a library JSP authors have, especially if you modify the library often); the JSP version the library depends on; a recommended prefix for the library; and the URI that the library is known by. Notice that I have used the prefix short-name as part of my URI, making it easy to visually connect the prefix to the library URI.

The rest of the information applies to a specific tag, denoted with the tag element. I've specified the name of the tag, the class for the tag (which should be compiled and in-place for container loading), and finally whether the tag has any nested content. In this case, it does not, so the "empty" value is used.

Save this file and place it in your WEB-INF/tlds directory (you may have to create this directory in your container). I saved mine as site-utils.tld, again creating a clear link between the library's URI, suggested prefix, and the TLD file itself. The final step in making your library available is to let your Web application know how to connect the URI in a JSP page, requesting usage of a tag library, with this specific library. This is done through the web.xml file for your application. Listing 3 shows a very simple web.xml fragment, which does just this for our tag library:

Listing 3. Linking a URI to a tag library

    <taglib>
      <taglib-uri>http://www.newInstance.com/taglibs/site-utils</taglib-uri>
      <taglib-location>/WEB-INF/tlds/site-utils.tld</taglib-location>
    </taglib>

Wrapping up
If you've followed along with each step so far, you should now be able to reference your new tag in a JSP page. Listing 4 shows our new-and-improved footer.jsp, completely devoid of scriptlets or references to JSP pages that have scriptlets:

Listing 4. Using the new tag library

<%@ taglib prefix="site-utils"
             uri="http://www.newInstance.com/taglibs/site-utils" %>
          </td>
          <td width="16" align="left" valign="top"> </td>
    </tr>
    <!-- End main content -->

<!-- Begin footer section -->
    <tr>
      <td width="91" align="left" valign="top" bgcolor="#330066"> </td>
      <td align="left" valign="top"> </td>
      <td class="footer" align="left" valign="top"><div align="center"><br>
        &copy; 2003 
        <a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
        Last Updated: <site-utils:lastModified />
        </div></td>
      <td align="left" valign="top"> </td>
      <td width="141" align="right" valign="top" bgcolor="#330066"> </td>
    </tr>
</table>
<!-- End footer section -->

After seeing how JSTL worked in previous installments (see "Update your JSP pages with JSTL" and "Import content to your Web site"), the next step should be clear to you: we reference the tag library using the URI from the web.xml file, assign it a prefix (the short-name from the TLD is always the best choice), and then use the library just like any other JSP tag. The result is a cleaner, better JSP page, which works just as well as it did when scriptlets were involved.

In the next installment, we'll extend the functionality of our current, rather simple, custom tag. Until then, see you online.

Resources

About the author
Photo of Brett McLaughlinBrett McLaughlin has been working in computers since the Logo days (remember the little triangle?). He currently specializes in building application infrastructure using Java and Java-related technologies. He has spent the last several years implementing these infrastructures at Nextel Communications and Allegiance Telecom Inc. Brett is one of the co-founders of the Java Apache project Turbine, which builds a reusable component architecture for Web application development using Java servlets. He is also a contributor of the EJBoss project, an open source EJB application server, and Cocoon, an open source XML Web-publishing engine. Contact Brett at brett@oreilly.com.


68 KBe-mail it!

What do you think of this document?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Comments?



developerWorks > Java technology
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact