- 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.6 Example: Packaging the Company Name Listeners
The listeners shown in Sections 10.2 and 10.4 are very effective in keeping track of the current and former company names. However, the pages that display the names (index.jsp, Listing 10.3 and company-info.jsp, Listing 10.4) are a bit difficult to read and maintain. This difficulty is due to the need for checking if the former company name is missing before trying to display it, a test that results in quite a bit of explicit Java code in the JSP page. A perfect job for a simple custom tag!
Listings 10.14 and 10.15 show custom tags that print out the current and former company names, respectively. The first tag simply prints the current company name. The second tag uses a fullDescription attribute to decide whether to simply print the former company name (e.g., some-company.com) or the company name inside parentheses (e.g., (formerly some-company.com)). Listing 10.16 shows the TLD file for this library: the listener elements of Sections 10.2 and 10.4 are moved out of the web.xml file and into the TLD file, which is then placed in the WEB-INF directory. Listing 10.17 shows the web.xml file: the previous listener elements are removed, and a taglib entry is added that makes it easier to update the name of the TLD file and lets the listeners be detected at Web application startup time by Tomcat 4.0.
Finally, Listings 10.18 and 10.19 show the company home page (see Listing 10.3) and company information page (see Listing 10.4) reworked with the new custom tags. Note that for the uri attribute of the taglib directive, these pages use "/company-name-taglib.tld" (the alias defined with the web.xml taglib element), not "/WEB-INF/company-name-taglib.tld" (the real location). Figures 109 and 1010 show the resultsidentical to those shown earlier in Figures 101 and 102.
Figures 109 Reworking the company home page to use custom tags results in an identical appearance (compare Figures 101) but yields JSP code that is significantly easier to read and maintain.
Figures 1010 Reworking the company information page to use custom tags results in an identical appearance (compare Figures 102) but yields JSP code that is significantly easier to read and maintain.
Listing 10.14 CompanyNameTag.java
package moreservlets.tags; import javax.servlet.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import moreservlets.listeners.*; /** The InitialCompanyNameListener class has static * methods that permit access to the current and former * company names. But, using these methods in JSP requires * explicit Java code, and creating beans that provided * the information would have yielded a cumbersome result. * So, we simply move the code into a custom tag. */ public class CompanyNameTag extends TagSupport { public int doStartTag() { try { ServletContext context = pageContext.getServletContext(); String companyName = InitialCompanyNameListener.getCompanyName(context); JspWriter out = pageContext.getOut(); out.print(companyName); } catch(IOException ioe) { System.out.println("Error printing company name."); } return(SKIP_BODY); } }
Listing 10.15 FormerCompanyNameTag.java
package moreservlets.tags; import javax.servlet.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*; import moreservlets.listeners.*; /** The InitialCompanyNameListener class has static * methods that permit access to the current and former * company names. But, using these methods in JSP requires * explicit Java code, and creating beans that provided * the information would have yielded a cumbersome result. * So, we simply move the code into a custom tag. */ public class FormerCompanyNameTag extends TagSupport { private boolean useFullDescription = false; public int doStartTag() { try { ServletContext context = pageContext.getServletContext(); String formerCompanyName = InitialCompanyNameListener.getFormerCompanyName(context); JspWriter out = pageContext.getOut(); if (useFullDescription) { String formerCompanyDescription = ""; if (!formerCompanyName.equals("")) { formerCompanyDescription = "(formerly " + formerCompanyName + ")"; } out.print(formerCompanyDescription); } else { out.print(formerCompanyName); } } catch(IOException ioe) { System.out.println("Error printing former company name."); } return(SKIP_BODY); } /** If the user supplies a fullDescription attribute * with the value "true" (upper, lower, or mixed case), * set the useFullDescription instance variable to true. * Otherwise, leave it false. */ public void setFullDescription(String flag) { if (flag.equalsIgnoreCase("true")) { useFullDescription = true; } } /** Servers are permitted to reuse tag instances * once a request is finished. So, this resets * the useFullDescription field. This method * is automatically called after the system is * finished using the tag. */ public void release() { useFullDescription = false; } } <?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"> <!-- a tag library descriptor --> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>company-name-tags</short-name> <description> A tag library to print out the ever-changing current and former company names (which are monitored by event listeners). </description> <!-- Register the listener that sets up the initial company name. --> <listener> <listener-class> moreservlets.listeners.InitialCompanyNameListener </listener-class> </listener> <!-- Register the listener that monitors changes to the company name. --> <listener> <listener-class> moreservlets.listeners.ChangedCompanyNameListener </listener-class> </listener> <!-- Define a tag that prints out the current name. --> <tag> <name>companyName</name> <tag-class>moreservlets.tags.CompanyNameTag</tag-class> <body-content>empty</body-content> <description>The current company name</description> </tag> <!-- Define a tag that prints out the previous name. --> <tag> <name>formerCompanyName</name> <tag-class>moreservlets.tags.FormerCompanyNameTag</tag-class> <body-content>empty</body-content> <description>The previous company name</description> <attribute> <name>fullDescription</name> <required>false</required> </attribute> </tag> </taglib>
Listing 10.17 web.xml (Excerpt for custom tags)
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <!-- Removed declarations for initial and changed company name listeners. They are now in TLD file. --> <!-- ... --> <!-- Register the company-name tag library. --> <taglib> <taglib-uri> /company-name-taglib.tld </taglib-uri> <taglib-location> /WEB-INF/company-name-taglib.tld </taglib-location> </taglib> <!-- ... --> </web-app>
Listing 10.18 index2.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <%@ taglib uri="/company-name-taglib.tld" prefix="msajsp" %> <TITLE><msajsp:companyName/></TITLE> <LINK REL=STYLESHEET HREF="events-styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> <msajsp:companyName/><BR> <msajsp:formerCompanyName fullDescription="true"/> </TABLE> <P> Welcome to the home page of <B><msajsp:companyName/></B> <msajsp:formerCompanyName fullDescription="true"/> <P> <B><msajsp:companyName/></B> is a high-flying, fast-growing, big-potential company. A perfect choice for your retirement portfolio! <P> Click <A HREF="company-info2.jsp">here</A> for more information. </BODY>
Listing 10.19 company-info2.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <%@ taglib uri="/company-name-taglib.tld" prefix="msajsp" %> <TITLE><msajsp:companyName/></TITLE> <LINK REL=STYLESHEET HREF="events-styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> <msajsp:companyName/><BR> <msajsp:formerCompanyName fullDescription="true"/> </TABLE> <P> Learn more about <B><msajsp:companyName/></B> <msajsp:formerCompanyName fullDescription="true"/> <UL> <LI><A HREF="products.jsp"><msajsp:companyName/> products</A> <LI><A HREF="services.jsp"><msajsp:companyName/> services</A> <LI><A HREF="history.jsp"><msajsp:companyName/> history</A> <LI><A HREF="invest.jsp">investing in <msajsp:companyName/></A> <LI><A HREF="contact.jsp">contacting <msajsp:companyName/></A> </UL> </BODY> </HTML>