- Monitoring Creation and Destruction of the Servlet Context
- Example: Initializing Commonly Used Data
- Detecting Changes in Servlet Context Attributes
- Example: Monitoring Changes to Commonly Used Data
- Packaging Listeners with Tag Libraries
- Example: Packaging the Company Name Listeners
- Recognizing Session Creation and Destruction
- Example: A Listener That Counts Sessions
- Watching for Changes in Session Attributes
- Example: Monitoring Yacht Orders
- Using Multiple Cooperating Listeners
- The Complete Events Deployment Descriptor
10.5 Packaging Listeners with Tag Libraries
JSP tag libraries (Section 3.7, Chapter 11) provide a great way of encapsulating content that will be accessed by multiple JSP pages. But what if that content depends on life-cycle event listeners? If the listener and listener-class elements of web.xml were the only option for declaring listeners, tag library maintenance would be much more difficult. Normally, the user of a tag library can deploy it by simply dropping a JAR file in WEB-INF/lib and putting a TLD file in WEB-INF. Users of the tag libraries need no knowledge of the individual classes within the library, only of the tags that the library defines. But if the tag libraries used listeners, users of the libraries would need to discover the name of the listener classes and make web.xml entries for each one. This would be significantly more work.
Fortunately, the JSP 1.2 specification lets you put the listener declarations in the tag library descriptor file instead of in the deployment descriptor. But, wait! Event listeners need to run when the Web application is first loaded, not just the first time a JSP page that uses a custom library is accessed. How does the system handle this? The answer is that, when the Web application is loaded, the system automatically searches WEB-INF and its subdirectories for files with .tld extensions and uses all listener declarations that it finds. This means that your TLD files must be in the WEB-INF directory or a subdirectory thereof. In fact, although few servers enforce the restriction, the JSP 1.2 specification requires all TLD files to be in WEB-INF anyhow. Besides, putting the TLD files in WEB-INF is a good strategy to prevent users from retrieving them. So, you should make WEB-INF the standard TLD file location, regardless of whether your libraries use event handlers.
Core Approach
Always put your TLD files in the WEB-INF directory or a subdirectory thereof.
Unfortunately, there is a problem with this approach: Tomcat 4.0 improperly ignores TLD files at Web application startup time unless there is also a taglib entry in web.xml of the following form:
<taglib> <taglib-uri>/someName.tld</taglib-uri> <taglib-location>/WEB-INF/realName.tld</taglib-location> </taglib>
As discussed in Section 5.13 (Locating Tag Library Descriptors), this entry is a good idea when the name of your tag library changes frequently. However, the JSP 1.2 specification does not require its use, and servers such as ServletExec 4.1 properly handle listener declarations in TLD files when there is no such entry. Nevertheless, Tomcat 4.0 requires it.
Core Warning
Tomcat 4.0 only reads listener declarations from TLD files that have taglib entries in web.xml.
Since listener declarations are a new capability in version 1.2 of the JSP specification, you must use the JSP 1.2 format of the tag library descriptor file. This format differs in two ways from the JSP 1.1 format.
First, the DOCTYPE declaration must use the JSP 1.2 Document Type Definition (DTD), not the 1.1 one. Here is the JSP 1.2 version:
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
Here is the JSP 1.1 version:
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
Second, a number of elements within the TLD file have changed their names slightly. In particular, hyphens were added to the tlibversion, jspversion, shortname, tagclass, and bodycontent elements. Also, the info element was renamed to description. These changes are summarized in Table 10.1.
Table 10.1 Changes in tag library element names. You must use the new element names if you use the 1.2 DTD (which is required if you use new capabilities such as listeners).
JSP 1.2 Name |
JSP 1.1 Name |
tlib-version |
tlibversion |
jsp-version |
jspversion |
short-name |
shortname |
description |
info |
tag-class |
tagclass |
body-content |
bodycontent |
Given the changes to the DOCTYPE declaration and the element names, Listing 10.12 shows the template for a TLD file in JSP 1.2. For comparison, Listing 10.13 shows the JSP 1.1 template.
Listing 10.12 JSP 1.2 Tag Library Descriptor (Template)
<?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>some-name</short-name> <description> Tag library documentation. </description> <taglib> <!-- listener elements, if any, each of the following form: <listener> <listener-class>somePackage.SomeListener</listener-class> </listener> --> <tag> <name>tagName</name> <tag-class>somePackage.SomeTag</tag-class> <body-content>...</body-content> <description>Tag documentation.</description> </tag> <!-- Other tag elements, if any. --> </taglib>
Listing 10.13 JSP 1.1 Tag Library Descriptor (Template)
<?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"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>some-name</shortname> <info> Tag library documentation. </info> <taglib> <tag> <name>tagName</name> <tagclass>somePackage.SomeTag</tagclass> <bodycontent>...</bodycontent> <info>Tag documentation.</info> </tag> <!-- Other tag elements, if any. --> </taglib>