How to handle exceptions in JSP
- Details
- Written by Nam Ha Minh
- Last Updated on 21 July 2019   |   Print Email
Generally, there are three ways to handle exceptions in a JSP page:
- Catching the exceptions directory in the JSP page.
- Specifying a separate JSP error page using page directive. This is called page-level exception handling.
- Configuring mapping of exception types-error pages in web.xml file (application-level exception handling).
Let’s take closer look at each approach in details with their own benefit and drawback.
1. Catching exceptions directly in JSP page
This is the simplest way, as we place a try-catch block directly into the JSP page, for example:
<%@ page language="java" %> <html> <body> <% try { int x = Integer.parseInt(request.getParameter("x")) ; %> <h2>You pass the number: <%=x%></h2> <% } catch (NumberFormatException ex) { %> <h2>Error: x must be a number</h2> <% } %> </body> </html>
The above code snippet tries to parse a number from a parameter which is passed from URL query string. If the parameter is not a number (indicated by the NumberFormatException is thrown), shows an error message.
Following is a more meaningful example which is a JSP page that calculates sum of two numeric parameters passed from query string:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Sum calculation</title> </head> <body> <%! int x; int y; %> <% try { x = Integer.parseInt(request.getParameter("x")) ; } catch (NumberFormatException ex) { %> <h2>Error: x must be a number</h2> <% return; } try { y = Integer.parseInt(request.getParameter("y")) ; } catch (NumberFormatException ex) { %> <h2>Error: y must be a number</h2> <% return; } %> <h1> Sum of <%=x%> and <%=y%> is <%=(x + y) %> </h1> </body> </html>
If the two parameters are numeric, the page displays sum of them:
If either a number is not numeric, an appropriate error message is displayed:
Benefits:
- Quick and easy to implement, just like traditional exception handling in pure Java code.
- Suitable for specific, recoverable errors which the application’s workflow can continue in case the exceptions occurred.
Drawbacks:
- This approach is generally not recommended, because it’s not a good practice to put Java code directly into JSP pages which are designed to represent view layer, not containing logic code.
- It’s inefficient if we want to handle exceptions for many JSP pages as with this approach, it requires to duplicate try-catch blocks in every single JSP page.
2. Page-level exception handling
In this way, we use JSP page directives to specify a separate error page which will be redirected in case exceptions occurred in the normal JSP page. The following diagram depicts this approach:
With this approach, there are two attributes of the page directive we have to specify for handling exceptions:
- errorPage=”path/to/error/handling/page”: Used in the JSP page in which exceptions might occur. This specifies an alternate JSP page which is written solely for handling exceptions such as showing exception class name, error message and exception stack trace. When the code in this page throws an exception, the server will redirect the client to the specified error handling page.
- isErrorPage=”true”: Used to indicate a JSP page is an error handling page so that the server will pass the exception object thrown by the original JSP page. The exception object is a subclass of java.lang.Throwable class so we can access the following details:
Let’s see an example. Consider the following JSP page:
<%@ page language="java" contentType="text/html; charset=UTF-8" errorPage="error_jstl.jsp" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Calculate division of two numbers</title> </head> <body> <% int x = Integer.parseInt(request.getParameter("x")); int y = Integer.parseInt(request.getParameter("y")); int div = x / y; %> <h2>Division of <%=x%> and <%=y%> is <%=div%></h2> </body> </html>
This page calculates division of two numbers passed from parameters query string. There are two possible exceptions here:
- The passed parameters do not have numeric values (a NumberFormatException will be thrown).
- The dividing number is zero (an ArithmeticException will be thrown).
And here is code of the error handling page (error.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" isErrorPage="true" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error</title> </head> <body> <h2> Error: <%=exception.getClass().getName() %><br/> <%=exception.getMessage() %><br/> </h2> </body> </html>
Here are some outputs when running this example:
- If two parameters are numeric:
- If either a parameter is not numeric:
- If the dividing number is zero:
Apart from accessing the exception object using JSP scriptlet, we can use JSTL to achieve the same goal in a more convenient way. For example:
Error: ${pageContext.exception}
To print the exception stack traces using JSTL:
<c:forEach var="trace" items="${pageContext.exception.stackTrace}"> ${trace}<br/> </c:forEach>
Here is a better version of the error.jsp page using JSTL:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page language="java" contentType="text/html; charset=UTF-8" isErrorPage="true" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Error</title> </head> <body> <h2> Error: ${pageContext.exception} <br/> </h2> Exception stack trace:<br/> <c:forEach var="trace" items="${pageContext.exception.stackTrace}"> ${trace}<br/> </c:forEach> </body> </html>
Output:
Benefits:
- This page-level exception handling in JSP is more convenient than using try-catch blocks, as we can create separate error handling page and re-use it across JSP pages.
Drawbacks:
- This approach specifies one error handling page for all kind of exceptions, so we can’t specify error page per exception type. For example: dbError.jsp for java.sql.SQLException, ioError.jsp for java.io.IOException, etc.
- Error handling configuration is depending on JSP pages: Whenever a new JSP page is added, we have to specify the attribute errorPageof the page directive. When file name of an error page is changed, we have to update all the referenced JSP pages as well.
3. Application-level exception handling
In this way, we can configure error handling page per exception type for all JSPs and servlets of the web application, by adding some entries in the web.xml file. Here is the syntax for configuring an error page for a specific exception type:
<error-page> <exception-type>fully_qualified_name_of_exception_class</exception-type> <location>path_to_error_jsp_page</location> </error-page>
For example:
<error-page> <exception-type>java.sql.SQLException</exception-type> <location>/dbError.jsp</location> </error-page>
That will tell the server to redirect the clients to the dbError.jsp page whenever any JSP/Servlet throws an exception of type java.sql.SQLException. The dbError.jsp page does not have to declare the attribute isErrorPage.
Using this approach we can also specify a custom error handling page for specific HTTP error code like 404, 500… The syntax is:
<error-page> <error-code>HTTP_error_code</error-code> <location>path_to_error_jsp_page</location> </error-page>
For example:
<error-page> <error-code>404</error-code> <location>/404error.jsp</location> </error-page>
That will tell the server redirects all requests causing HTTP 404 error to the custom page 404error.jsp, instead of showing the default 404 error. Following is example code of the 404error.jsp page:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>404 Error</title> </head> <body> <center> <h2> Apologize, we could not find the page you were looking for: </h2> ${pageContext.errorData.requestURI} </center> </body> </html>
The errorData object provides detailed information about the error such as the request URI, status code, servlet name, and the Throwable object that caused the error:
Here is the output when trying to access non-exist URL on the server:
Benefit:
- This application-level error handling is easy to use and independent of JSP pages so this is the most preferred way for exception handling in JSP.
Drawback:
- The only drawback for this approach is that, every changes made to the configuration requires application/server restart, because the configuration is done in the web.xml file.
Related Java Exception Handling Tutorials:
- Getting Started with Exception Handling in Java
- How to Handle Error in Web.xml for Java web applications
Other JSP Tutorials:
- Summary of EL operators with examples
- Java Servlet and JSP Hello World Tutorial with Eclipse, Maven and Apache Tomcat
- How to list records in a database table using JSP and JSTL
- How to create dynamic drop down list in JSP from database
- Sending e-mail with JSP, Servlet and JavaMail
Comments