Book: JavaServer Pages™, 2nd Edition
Section: Chapter 7.  Using Custom Tag Libraries and the JSP Standard Tag Library



7.3 Declaring a Custom Tag Library

As you know by now, a JSP page contains a mixture of JSP elements and template text, in which the template text can be HTML or XML elements. The JSP container needs to figure out which is which. It's easy for it to recognize the standard JSP elements (because they all use the jsp namespace prefix), but it needs some help to find which elements represent custom actions. That's where the tag library declaration comes into play.

Example 7-1 shows a page that uses a custom action from a custom tag library.

Example 7-1. Custom tag library declaration (message.jsp)
<%@ page contentType="text/html" %>
<%@ taglib prefix="ora" uri="orataglib" %>
<html>
  <head>
    <title>Messages of the Day</title>
  </head>
  <body bgcolor="white">
    <h1>Messages of the Day</h1>
    <h2>Deep Thoughts - by Jack Handey</h2>
    <i>
      <ora:motd category="thoughts" />
    </i>
  
    <h2>Quotes From the Famous and the Unknown</h2>
    <i>
      <ora:motd category="quotes" />
    </i>
  </body>
</html>

This page displays messages from the same collections as the examples in Chapter 6. The second directive in Example 7-1 is a taglib directive, which is used to declare a custom tag library. Now, let's see what this really means. In order for the JSP container to use actions from a tag library, it must be able to do two things: recognize that an element represents a custom action from a specific library and find the Java class that implements the custom action logic.

The first requirement -- figuring out which library an action belongs to -- is satisfied by the taglib directive's prefix attribute; all elements in the page that use the specified prefix belong to this custom tag library. A custom tag library defines a default prefix, used in the library's documentation and possibly by page-authoring tools that insert custom action elements in a page. You can, however, use any prefix you like except jsp, jspx, java, javax, servlet, sun, or sunw (those are reserved by the JSP specification). The prefix I use for all custom actions in this book is ora, short for "O'Reilly & Associates, Inc."

The uri attribute satisfies the second requirement; finding the class for each custom action. The attribute contains a string the container uses to locate the TLD for the library, where it finds the Java class names for all actions in the library. The value can identify the TLD file in a number of ways, but if you use a JSP 1.2 container, there's really just one way that you need to care about: the default URI for the library. The default URI should be part of the documentation for the library. It's orataglib for the custom tag library described in this book.

When the web application is started, the container scans through the WEB-INF directory structure for files with .tld extensions (the mandatory extension for a TLD file) and all JAR files containing files with .tld extensions in their META-INF directory. In other words, the container locates all TLD files. For each TLD, the container gets the library's default URI from the TLD and creates a map from the URI to the TLD that contains it. In your JSP page, you just have to use a taglib directive with a uri attribute value that matches the default URI.

For this to work in an environment where custom tag libraries can come from multiple vendors as well as from inhouse staff, the default URI value must be a globally unique string. A common convention is to use an HTTP URL, such as http://ora.com/jsptags. This is one way to be reasonably sure that the value is unique, and it's the choice made for all JSTL tag library URIs. Note that the URL doesn't have to refer to an existing web page; it's just an identifier, and the container doesn't try to access it over the Internet. Others prefer a shorter string, such as orataglib or com.ora.jsptags. This works equally well as long as the strings are unique in the application.

With the URI and the prefix for the library defined, the container has all it needs to find the class that implements the custom action's behavior. As shown in Figure 7-1, when the container finds an element with a prefix matching a prefix defined by a taglib directive, it uses the uri attribute value to locate the TLD. In the TLD, it finds a mapping between the action element name and the class file.

Figure 7-1. Relation between the taglib directive, the TLD, and the tag handler class
figs/Jsp2_0701.gif

7.3.1 Identifying a Custom Tag Library in a JSP 1.1 Container

Prior to JSP 1.2, the container didn't locate custom tag libraries automatically. If you're stuck with a container that doesn't yet support JSP 1.2, you must tell it exactly where to find the TLD.

The first approach you can use is to specify a symbolic name as the uri attribute value, just as in JSP 1.2. But in addition, you must define the mapping from the symbolic name to the location of the library in the deployment descriptor for the application (WEB-INF/web.xml):

<web-app>  
  ...  
  <taglib>    
    <taglib-uri>      
      orataglib    
    </taglib-uri>    
    <taglib-location>      
      /WEB-INF/lib/orataglib_2_0.jar
    </taglib-location>
  </taglib>
  ...
</web-app>

The <taglib-uri> element contains the symbolic name, and the <taglib-location> element contains the path to the tag library JAR file or to the TLD file itself in case the library isn't packaged in a JAR file.

If the uri attribute value doesn't match a symbolic name defined in the web.xml file, the container assumes it is a file path:

<%@ taglib uri="/WEB-INF/lib/orataglib_2_0.jar" prefix="ora" %>

If the path starts with a slash, it's interpreted as a context-relative path (the path to the file from the root of the application installation directory), otherwise as a path relative to the JSP page. The file can be either the TLD file itself or a JAR file that includes the TLD file as META-INF/taglib.tld.

These two approaches work in JSP 1.2 container as well, but there's rarely a reason to use them because the auto-discovery feature makes life so much easier.

    [http://safari.oreilly.com/059600317X/jserverpages2-CHP-7-SECT-3]


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