Global Exception configuration using web.xml, servlet and jsp

You may also like to read:

Introduction

This tutorial will show how we can configure exception/error handling globally using deployment descriptor, servlet and jsp in our web applications. The aim of this tutorial is to teach whenever an exception or error occurs in an web based application, then that exception or error would be thrown in an appropriate manner. The error page is finally shown to the end users with the exception or error information in jsp page.

For this we do not need to create as many jsp pages or servlets as many exceptions occur rather we will create just one servlet for capturing exceptions or errors and only one jsp page for displaying error information to the end users.

We need to put necessary configurations for the exceptions in web.xml file.

We can provide link to the application home page or some details about the error information to let user know what went wrong in the application. But to keep things simple we won’t have such link to provide more details on errors.

Prerequisites

Knowledge of Java, JSP and Servlet

Servlet dependency in pom.xml file

Example

Project Structure

Below figure shows the overall project structure created in Eclipse IDE:

global exception configuration using web.xml, servlet and jsp

Build file – pom.xml

Once you create maven based web project in Eclipse then update your pom.xml file to match the below file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>ca.cn.cc</groupId>
	<artifactId>web-app-global-exceptions</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>web-app-global-exceptions</finalName>
	</build>
</project>

In the above build file we have added only one dependency with provided scope because servlet & jsp APIs are available in the Tomcat or any Java based web server.

Creating JSP pages – index.jsp & error.jsp

The index.jsp page is nothing but shows welcome page with simple message about the application:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Web Application Global Exception</title>
</head>
<body>
	<div>Servlet Exception example</div>
</body>
</html>

The below error/error.jsp page will be rendered when you are accessing a URL, which is not found or which is not allowed to access etc.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" isErrorPage="true"%>
<!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=ISO-8859-1">
<title>Web Application Global exception - error page</title>
</head>
<body>
	<p>${errorMsg}</p>
</body>
</html>

Creating Servlet – ExceptionHandler

We can have multiple servlets depending upon the type of exceptions or errors in your application but for simplicity I will create only one servlet and use it for both exceptions and errors.

Below is the ExceptionHandler servlet source code:

package com.jeejava.servlets;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ExceptionHandler
 */
@WebServlet("/ExceptionHandler")
public class ExceptionHandler extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ExceptionHandler() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		cathException(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		cathException(request, response);
	}

	private void cathException(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
		Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
		String servletName = (String) request.getAttribute("javax.servlet.error.servlet_name");

		if (servletName == null) {
			servletName = "Unknown Path Segment";
		}

		String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri");

		if (requestUri == null) {
			requestUri = "Unknown Request URI";
		}

		if (throwable == null && statusCode == null) {
			String msg = "Error information is missing";
			msg += "Please return to the Home Page";
			request.setAttribute("errorMsg", msg);
		} else if (statusCode != null) {
			String msg = "Status Code: " + statusCode + " ";
			msg += "For more information on status code please go to Status Code Definitions";
			request.setAttribute("errorMsg", msg);
		} else {
			String msg = "Error information";
			msg += "Servlet Name : " + servletName + " ";
			msg += "Exception Type : " + throwable.getClass().getName() + "";
			msg += "The request URI: " + requestUri + " ";
			msg += "The exception message: " + throwable.getMessage();
			request.setAttribute("errorMsg", msg);
		}

		RequestDispatcher requestDispatcher = request.getRequestDispatcher("/error/error.jsp");
		requestDispatcher.forward(request, response);
	}
}

In the above servlet class, most of the things are self-explanatory.

When exception or error scenario occurrs, servlet container will invoke the corresponding HTTP method of the ExceptionHandler servlet and pass the request and response object. Here I have provided implementation for both doGet() and doPost() methods using a common method cathException() to handle the exceptions or errors in both methods.

Before servlet container invokes the servlet to handle the exception, it sets some attributes in the request to get useful information about the exception, some of them are javax.servlet.error.exception, javax.servlet.error.status_code, javax.servlet.error.servlet_name and javax.servlet.error.request_uri.

Deployment Descriptor – web.xlml

Let’s configure the deployment descriptor file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>ca.cn.cc</groupId>
	<artifactId>web-app-global-exceptions</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>web-app-global-exceptions</finalName>
	</build>
</project>

As you can see in the above source code, it’s very easy to specify ExceptionHandler servlet for the application using error-page element. Each error-page element should have either error-code or exception-type element. We define the ExceptionHandler servlet in location element.

<error-page>
<error-code>404</error-code>
<location>/ExceptionHandler</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/ExceptionHandler</location>
</error-page>

Based on above configuration, if the application throws 404 error, 403 error or any kind of exception then it will be handled by ExceptionHandler servlet.

We can also configure different error page for different exception type but I have used

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/ExceptionHandler</location>
</error-page>

for all kind of exception handling in one line.

Now when we hit our servlet or any url that is throwing Exception, we get a response like the below:

global exception configuration using web.xml, servlet and jsp
global exception configuration using web.xml, servlet and jsp

Source code can be downloaded from here.

Thanks for your reading. Please leave a comment if you have any query.

Global Exception configuration using web.xml, servlet and jsp

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top