Mastering Custom Error Pages in Tomcat with Spring MVC

Snippet of programming code in IDE
Published on

Mastering Custom Error Pages in Tomcat with Spring MVC

In web applications, user experience is paramount. One of the most critical aspects of that experience is handling errors gracefully. Instead of displaying generic error messages that can confuse users, we can present custom error pages that are informative and aligned with our application’s branding. In this post, we will dive deep into how to master custom error pages in a Spring MVC application deployed on Tomcat.

Why Custom Error Pages Matter

  1. Branding: Custom error pages reinforce the brand identity of your application.
  2. User Guidance: They help guide users back to a productive path, offering ways to navigate the site instead of leaving them stranded.
  3. Reduced Bounce Rates: By providing users with clear instructions on what to do next, we can often keep them on the site, leading to reduced bounce rates.

With that said, let's consider how we can implement custom error pages in a Spring MVC application running on Tomcat.

Prerequisites

Before we dive into the implementation, ensure that you have:

  • A basic understanding of Spring MVC.
  • Tomcat server set up and running.
  • A working Spring MVC project.

1. Setting Up Spring MVC

If you haven’t already set up a Spring MVC project, here’s a minor snippet to give you a direction:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.13</version>
</dependency>

You'll also need a basic configuration file, such as web.xml:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
         version="3.1">
    <servlet>
        <servlet-name>springDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springDispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

2. Creating Custom Error Pages

To create custom error pages, you will follow these main steps:

  • Define error pages in the web.xml.
  • Create the respective HTML files for display.
  • Configure error handling in your Spring MVC application.

Step 1: Define Error Pages in web.xml

The first step towards creating custom error pages is to map the specific error codes to your custom HTML files for these HTTP errors.

<error-page>
    <error-code>404</error-code>
    <location>/error/404.html</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/error/500.html</location>
</error-page>

Each <error-page> block specifies the error code and the location of the HTML file to render when that error occurs.

Step 2: Creating the Custom HTML Error Pages

Now, let’s create the error pages 404.html and 500.html files inside the src/main/webapp/error directory.

404.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Page Not Found</title>
</head>
<body>
    <h1>404 - Page Not Found</h1>
    <p>Sorry, the page you are looking for does not exist.</p>
    <a href="/">Go to Home</a>
</body>
</html>

500.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Internal Server Error</title>
</head>
<body>
    <h1>500 - Internal Server Error</h1>
    <p>Oops! Something went wrong on our end. Please try again later.</p>
    <a href="/">Go to Home</a>
</body>
</html>

3. Configuring Error Handling in Spring MVC

In addition to server-level error pages, we can also handle errors at the application level using @ControllerAdvice.

Creating a Global Exception Handler

Here’s how to create a global exception handler for your application:

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.http.HttpStatus;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handle404(NoHandlerFoundException ex, Model model) {
        model.addAttribute("message", "Requested page not found. Please check the URL.");
        return "error/404";
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handle500(Exception ex, Model model) {
        model.addAttribute("message", "Internal Server Error: " + ex.getMessage());
        return "error/500";
    }
}

Why Use @ControllerAdvice?

Using @ControllerAdvice allows you to define a single place where you handle a variety of exceptions thrown across your application. This practice aligns with the DRY (Don't Repeat Yourself) principle.

Testing Your Custom Error Pages

To test your newly created error pages:

  1. Deploy your application on Tomcat.
  2. Direct your browser to a non-existent URL (to test the 404 page).
  3. Force an internal error by throwing an exception in one of your controllers (to test the 500 page).

Example to intentionally throw an exception:

@GetMapping("/error-test")
public String errorTest() {
    throw new RuntimeException("Test Exception");
}

Additional Resources

My Closing Thoughts on the Matter

Benefits of custom error pages extend beyond aesthetics to create a better user experience. They keep users informed and help maintain your application's brand identity even when things don’t go as planned. Through the combination of Tomcat configuration and Spring MVC capabilities, you now have a comprehensive approach to manage errors efficiently.

Implementing these strategies will ensure that your application not only handles errors gracefully but also retains users even during unexpected situations.

Now you’re well-equipped to create stunning custom error pages in your Spring MVC applications deployed on Tomcat! Happy coding!