|
|
|
Contents: |
|
|
|
Related content: |
|
|
|
Subscriptions: |
|
|
| Try, catch, and fix error conditions in your custom
tags
Brett
McLaughlin (mailto:brett@oreilly.com?cc=&subject=Error
handling in custom tags) Author, O'Reilly and Associates 19
August 2003
As you introduce more interactivity into
your custom tags, you also introduce greater potential for error,
particularly in the form of invalid arguments. In this installment of
JSP pest practices, Brett McLaughlin shows you how to trap and
override an IllegalArgumentException at its
source.
Up to this point in our discussion of JSP custom tags, we've managed to
sidestep the important detail of error handling. Many of the best
practices that we addressed in the first half of the series dealt with
functionality provided by your JSP container, such as the
param , out , and import tags. In
these cases, error handling was the domain of the JSP specification and
Web server implementation, which means that even if we wanted to do
something about it we couldn't.
But the last two installments have focused on custom tag libraries and
attributes. We've not only begun adding new functionality to our JSP
pages, but we've created attributes that allow JSP authors to interact
with our code. Along the way, it's quite possible that we have introduced
a new type of error into our JSP pages, or that (at some later point) a
page author's mistake could wreak havoc with a tag's code and subsequent
output. In either case it has become imperative that we incorporate
error-handling into our custom tags.
A note about the examples: All of the example code we'll work
with in this installment of JSP best practices builds on the code
developed in the previous installment. You should be sure you have
successfully completed the setup and coding exercises from the previous
installment before continuing here.
Investigative redux We'll
start by retracing our steps through some of the code we developed in the
previous installment -- but this time we'll focus on discovering errors
(or the potential for errors) in the code.
First off, recall that we added a new attribute, format ,
to the lastModified tag. This attribute allows page authors
to pass in a format string, usable by the
java.text.SimpleDateFormat class, that customizes the format
of the last-modification date stamp. While this type of interactivity is
essential to most JSP pages, it does introduce the potential for errors in
our tag.
For example, a page author could easily supply an invalid format string
that would result in a nasty error message. To see what this might look
like, modify your footer file (or any other JSP page using the
lastModified tag) to look like the one shown in Listing
1: Listing 1. An invalid format string
<%@ 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>
© 2003
<a href="mailto:webmaster@newInstance.com">Brett McLaughlin</a><br>
Last Updated: <site-utils:lastModified
format="PHH:mm a, MM/dd/yyyy"/>
</div></td>
<td align="left" valign="top"> </td>
<td width="141" align="right" valign="top" bgcolor="#330066"> </td>
</tr>
</table>
<!-- End footer section -->
|
An invalid argument
example The "P " of the format string
"PHH:mm a, MM/dd/yyyy" in Listing 1 has been misplaced,
resulting in an invalid formatting string argument. In a Java class, this
type of error would cause an IllegalArgumentException to be
thrown. In a JSP environment, however, the error would be relayed to the
end-user, resulting in an error message similar to the one shown here.
This type of error message is bad enough for a page author to receive
and have to untangle; it's much worse if it gets past the author and goes
directly to an end user. In the worst-case scenario, the user would be
scared off the site by the error message and never return, resulting in
loss of publicity, revenue, and reputation -- all of which are extremely
important to any company!
Overriding an invalid
argument Fortunately, we can work around this type of error
by providing some basic error-handling capability in our custom tags. The
most simple form of error handling is to define default (or fallback)
behavior to override invalid arguments. In the example of the
lastModified tag, we have already created the first part of
an error-handling mechanism for this condition, by providing a default
format for our time stamp. However, it's better to define the default as a
constant, and then refer to the constant, rather than just assigning the
string default to a variable. Listing 2 shows how the
DEFAULT_FORMAT constant is added and assigned to the
format variable: Listing 2. Setting a
default format for the LastModifiedTag
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 {
private final String DEFAULT_FORMAT = "MMM d, yyyy";
private String format = DEFAULT_FORMAT;
public void setFormat(String format) {
this.format = format;
}
// doEndTag() method, as seen in previous tips
}
|
Of course, this default value can either be left as it is or modified
by the addition of a new format string. If the page author provides an
invalid format string, then he will receive an error message. So, in
addition to providing default behavior and a mechanism for modifying that
behavior, we need to provide a mechanism for reverting to the default
behavior in the case of an invalid format string. But before we can fix an
error, we need to catch it.
Try, catch, and fix In any
type of error handling, we want to catch the error at its source, which is
wherever it first becomes a problem. In this case, the invalid format
string will be passed to the SimpleDataFormat constructor,
where it will result in an IllegalArgumentException being
thrown. So we place a try/catch block on the constructor, as
shown in Listing 3: Listing 3. A try/catch block for
an invalid format string
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 {
private final String DEFAULT_FORMAT = "MMM d, yyyy";
private String format = DEFAULT_FORMAT;
public void setFormat(String format) {
this.format = format;
}
public int doEndTag() {
try {
HttpServletRequest request =
(HttpServletRequest)pageContext.getRequest();
String path = pageContext.getServletContext().getRealPath(
request.getServletPath());
File file = new File(path);
DateFormat formatter;
try {
formatter = new SimpleDateFormat(format);
} catch (IllegalArgumentException e) {
formatter = new SimpleDateFormat(DEFAULT_FORMAT);
}
pageContext.getOut().println(
formatter.format(new Date(file.lastModified())));
} catch (IOException ignored) { }
return EVAL_PAGE;
}
}
|
Note that lastModified output now reverts to the default
format string in the event of an IllegalArgumentException
being thrown. You can test this out by recompiling the tag with the new
code, restarting your servlet container, and accessing the page with the
invalid date format. Rather than a nasty stack trace, you should see a
normal-looking footer, displaying the last-modification date and time in
the format specified by DEFAULT_FORMAT .
Wrapping up Hopefully this
tip has shown the importance of including error-handling mechanisms in
your custom tags. Every new custom tag (and attribute) represents a unique
extension of the JSP platform, and so you must also provide a unique
solution to any problem that may arise out of that extension.
For a follow-up exercise to what you've learned here, try retracing
your steps through some of the custom tag libraries you've already
written. Now that you've developed an eye for it you'll likely discover at
least one or two error conditions in need of correction. Just remember the
simple try-catch-fix technique you learned here: locate the error at its
source, apply a mechanism to catch it, and then provide some type of
behavior to override it.
In the next installment of JSP best practices, we'll complete
our discussion of custom tag libraries by talking about packaging. You'll
learn how to package one or more custom tag libraries in a JAR file for
easier maintenance, distribution, and Web-container installation. Until
then, I'll see you online!
Resources
About the
author Brett 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. |
|
|