Understanding Basic Tag Logic in JSTL
- Exception Processing
- Using Conditionals
- A Chat Application
- Summary
The Core tag library of JSTL provides many rudimentary tags for performing basic flow control. Flow control refers to a program's ability to selectively execute portions of itself. Most programming languages achieve this flow control through if statements and other logical tags. A program's flow of execution can also be affected by errors.
Error handling is an important part of any computer program. JSP provides tags that let you perform basic error handling. By making use of JSTL's built-in exception-handling capabilities, you can create programs that are capable of handling common runtime errors.
In this chapter, we present a sample application that shows how to tie all these concepts together. A simple forms-based chat application will show you how to use scope and basic tag logic to allow two users to chat. Let's begin by examining JSTL's error-handling capabilities.
Exception Processing
Java programs handle errors through the use of exceptions. When a section of code is susceptible to throwing an exception, you can enclose that section of code in a try block. For example, when you're creating a new URL object, it is possible that an invalid URL will be provided to the object. If this happens, the URL object will throw a MalformedURLException. To properly handle this exception, the URL instantiation must be enclosed in a try block, and a catch must be provided that will catch the MalformedURLException. The following code illustrates this:
try { URL = new URL("http://www.sams.com"); } catch(MalformedURLException e) { }
Exception handling allows your program to react to errors that are not a result of bad program design. For example, exceptions could be trapped when the user enters invalid information, a URL fails to load, or when some other noncritical error occurs. By trapping these exceptions, you design your program to handle these errors as they happen so they don't result in a server error. This ensures that your Web pages present a consistent and robust interface.
JSTL provides the <c:catch> tag to handle this case. Before we examine how to catch an exception in JSTL, let's see what causes an exception to be thrown.
Generating Exceptions
Many of the JSTL tags are capable of throwing exceptions, yet JSTL is designed to throw exceptions as little as possible. Many errors that would generate an exception in Java or other programming languages are ignored in JSTL. Consider division by zero. Nearly any programming language ever produced will return some sort of an error if a division is specified with zero in the denominator. Yet in JSTL, this case does not generate an exception. Listing 3.1 demonstrates this.
Listing 3.1 Division by Zero (exception.jsp)
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %><html> <head> <title>Throw an Exception</title> </head> <body>10 divided by 0 is <c:out value="${10/0}" /> <br /> </body> </html>
As you can see, Listing 3.1 attempts to throw an exception by dividing 10 by 0. Under most circumstances, this would throw an exception. However, JSTL simply ignores this error and continues processing. As you learn more about JSTL error handling, you will see that in most cases, JSTL attempts to continue processing after an error has occurred. If you run the JSP code in Listing 3.1, you get the following output:
10 divided by 0 is infinity
While JSTL attempts to handle most exceptions as they occur, certain things can go wrong that will still cause JSTL to throw an exception. Listing 3.2 shows an example of an error that will throw an exception.
Listing 3.2 An Uncaught Exception (exception2.jsp)
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Throw an Exception</title> </head> <body> <c:set var="x" value="10" scope="page" /> <c:set var="y" value="five" scope="page" /> x divided by y is <c:out value="${x/y}" /> <br /> </body> </html>
Listing 3.2 attempts to throw an exception by causing a type mismatch. The value 10 is stored in the scoped variable x. The value five, the literal string, is stored in the scoped variable y. The program then attempts to divide x by y. While it is permissible to divide by zero in JSTL, it is not permissible to divide a string. When executed, Listing 3.2 will throw an exception. Because there is nothing set up to catch this exception, it will be thrown to the Web browser as a server error. Figure 3.1 shows this error message.
Figure 3.1 An uncaught JSTL exception is thrown.
It is important to understand which errors in JSTL will result in an exception and which errors will be ignored. In general, the following errors will cause an exception to be thrown.
Specification of an invalid scope
An empty var attribute in a tag
An invalid type
An invalid value
Invalid expressions
JSTL is very forgiving of most other errors. For example, null values, which often cause errors in other languages, are simply treated as empty strings.
Now that you have seen what can cause an exception, it is important to see how to handle exceptions. The next section covers how to catch exceptions in JSTL.
Using the <c:catch> Tag
JSTL provides the <c:catch> tag for catching exceptions. Any tags that are within the body of the <c:catch> tag will be handled. The <c:catch> tag is capable of catching any exception that is a subclass of java.lang.Throwable; this includes all Java exceptions. The following shows the structure of a <c:catch> tag:
<c:catch var="e"> ... Program code that may thrown an exception ... </c:catch>
One attribute is accepted by the <c:catch> tag:
Attribute |
Required |
Purpose |
var |
Y |
Specifies the scoped variable to receive the exception. |
Our previous sample would catch an exception and store it in the e variable. If an exception occurs inside the body of the <c:catch> tag, JSTL immediately continues executing with the line just after the ending </c:catch> tag. The variable specified in the var attribute, in this case e, will receive a copy of the exception that was thrown. If no exception is thrown, then the exception variable will receive a null value.
When inserting a <c:catch> tag in your code, make sure that the code handles both an exception being thrown and an exception not being thrown. Listing 3.3 shows the catch division-by-zero example with a <c:catch> tag ready to handle any errors.
Listing 3.3 Our Catch Division-by-Zero example (catch.jsp)
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Catch an Exception?</title> </head> <body> <c:catch var="e"> 10 divided by 0 is <c:out value="${10/0}" /> <br /> </c:catch> <c:if test="${e!=null}">The caught exception is: <c:out value="${e}" /> <br /> </c:if> <c:if test="${e==null}">No exception was thrown <br /> </c:if> </body> </html>
As you can see in the following code snippet, the division by zero is now wrapped in a <c:catch> tag. If any error occurs, the program will immediately exit the <c:catch> tag:
<c:catch var="e"> 10 divided by 0 is <c:out value="${10/0}" /> <br /> </c:catch>
Because the division by zero does not cause an exception, this program will glide through the catch and continue on with a null value assigned to the variable e. The program continues by checking this variable and displaying the error if it was set:
<c:if test="${e!=null}">The caught exception is: <c:out value="${e}" /> <br /> </c:if>
If an exception does occur, the program stores a value in the variable specified to the <c:catch> tag. Listing 3.4 shows an example of a program that will throw an exception. The line that generates the exception is protected by a <c:catch> tag. As a result, the exception will be handled internally by the JSP page.
Listing 3.4 Catching an Exception (catch2.jsp)
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head> <title>Catch an Exception</title> </head> <body> <c:catch var="e"> <c:set var="x" value="10" scope="page" /> <c:set var="y" value="five" scope="page" /> x divided by y is <c:out value="${x/y}" /> <br /> </c:catch> <br /> <c:if test="${e!=null}">The caught exception is: <c:out value="${e}" /> <br /> </c:if> <c:if test="${e==null}">No exception was thrown <br /> </c:if> </body> </html>
This program performs in exactly the same way as the division-by-zero example. However, in this case, the code following the <c:catch> tag actually has something to print. This sample program will display the following:
This text string identifies the exception that was thrown, and includes a message that describes why the error occurred.