Spring boot error 404

Manage a custom error page in Spring and fix the Whitelabel error page

image for 404 error

Sometimes it happens that the visitor writes incorrectly an URL or the page you created doesn’t exist anymore.

It’s important to return the correct code and if possible an explicit message to the user or to the search engine. 404 and 410 HTTP codes are used by Google search engine to remove old pages from their index. This avoids lowering the quality of your content because your server is showing empty pages or errors.

Here you can find the detail about how to remove permanently a page from Google.

How to return a HTTP 404 (Not found) or HTTP 410 (Gone) with Spring Boot?

If you are using @ResponseBody you can simply declare an exception:

throw new ResponseStatusException( 
  HttpStatus.NOT_FOUND, "the page is not found" 
); 

The NOT_FOUND enumerator returns a 404 error. From the Spring code: NOT_FOUND(404, Series.CLIENT_ERROR, "Not Found”),

By default, throwing ResponseStatusException will escalate the exception to the browser showing and non-user friendly presentation of our error message.

whitelabel error in spring

If you are on this post because of the Whitelabel Error Page deploying an Angular application … you are in the wrong post and you should go here: https://marco.dev/angular-spring-whitelabel

How can we avoid the ugly ‘Whitelabel Error Page’?

Spring Boot comes with an easy and smart solution. You can simply add a default page in your static assets with the name 404.html (or 410.html for the GONE HTTP message. Spring will automatically map the 404 error with the 404.html in the assets.

src/ 
 +- main/ 
     +- java/ 
     |   + <source code> 
     +- resources/ 
         +- public/ 
             +- error/ 
             |   +- 404.html 
             +- <other public assets> 

Here you have more details from the official Spring documentation

This path can be customized with the server.error.path Spring property (default: /error)

The whitelabel can be deactivated using properties: server.error.whitelabel.enabled=false

Custom ModelAndView

I prefer to handle the error page as View, if an exception is found in the backend I return a ModelAndView this gives me more flexibility if I want to send parameters (e.g. custom friendly message). Important is to give the HttpStatus.NOT_FOUND, for a ‘human’ user the http header is maybe not important but for search engines it’s very important and could avoid ‘damages’ to your SEO.

return new ModelAndView("not-found-page", HttpStatus.NOT_FOUND); 

browser console error

Deep dive into the ‘Whitelabel Error Page’

The properties of the Whitelabel and the error pages can be found here: ErrorProperties.java

This class defines the parameters name to customize the path of the error page and if the Whitelabel error is enabled or not.

The configuration of the Whitelabel is here in ErrorMvcAutoConfiguration.java

@Configuration(proxyBeanMethods = false) 
@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true) 
@Conditional(ErrorTemplateMissingCondition.class) 
protected static class WhitelabelErrorViewConfiguration { 
 
  private final StaticView defaultErrorView = new StaticView(); 
 
  @Bean(name = "error") 
  @ConditionalOnMissingBean(name = "error") 
  public View defaultErrorView() { 
    return this.defaultErrorView; 
  } 
 
  // If the user adds @EnableWebMvc then the bean name view resolver from 
  // WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment. 
  ... 
} 

The same class contains the implementation as you can see Spring returns a StaticView in other words a Servlet Response (servlet.View):

private static class StaticView implements View 
@Override 
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) 
... 
response.setContentType(TEXT_HTML_UTF8.toString()); 
StringBuilder builder = new StringBuilder(); 
... 
builder.append("<html><body><h1>Whitelabel Error Page</h1>").append( 
"<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>") 
... 
response.getWriter().append(builder.toString());} 
... 

A pretty common issue for Spring Boot application is a 404 Not Found Error for your REST Controllers. Let’s learn how to fix it in one minute!

Problem description

You are running a Spring Boot application which includes a REST Controller, as in this example:

package com.example.controller; 
@RestController // shorthand for @Controller and @ResponseBody rolled together
public class ExampleController {
   
   @RequestMapping( "/hello" )
   public String echo() {
      return "Hello World!";
   }

}

To run your Spring Boot application you are using an Application Main class:

package com.example.application;
@SpringBootApplication 
public class MainApp {
   public static void main( String[] args ) {
      SpringApplication.run( MainApp.class, args );
   }
}

Then, you request for the “/hello” endpoint but you get a 404 error:

$ curl http://localhost:8080/hello

{
  "timestamp": 9853742596220,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/hello"
}

How to fix the issue

To understand what is the issue, we need to focus on the @SpringBootApplication annotation. As a matter of fact, this annotation it’s a combination of three annotations:

@Configuration
@EnableAutoConfiguration
@ComponentScan

The default @ComponentScan annotation (without arguments) tells Spring to scan the current package and all of its sub-packages..

Therefore, only classes under the package “com.example.application” will be scanned. There are two ways to fix it.

Solution #1

The best practice is to place the Main Application class at the root of your project. This way, it will automatically scan and find the Controller class which are available in a sub-package. For example, here is a package structure that works:

spring boot controller not found

In the above project, we have placed the DemoApplication class at the root of other packages, therefore you will not have issues in finding other classes.

Solution #2

As another option, you could add to your @ComponentScan annotation the starting point used to scan for Classes:

@ComponentScan(basePackages = "com.myapp.demo")
@Configuration
public classDemoApplication {
   // ...
}

We have just covered some options to fix a common error in Spring Boot applications, related to REST Controller not found.

Details
Written by  
Last Updated on 24 March 2022   |   Print  Email

In this article, I will help you understand the default error handling in Spring Boot, how to use custom error pages (for common HTTP error codes like 403, 404, 500…) and how to code a custom error controller in order to perform additional code when an error occurred, e.g. logging more information about the error.

 

1. Default Whitelabel Error Page

By default, Spring Boot will display the Whitelabel error page when an error occurred. For example, when a page could not be found (HTTP 404 error):

spring boot whitelable error 404

Or when an exception is thrown by Java Virtual Machine, causing HTTP 500 Internal server error – the white label error page gets displayed with the exception stack trace:

spring boot whitelable error 500

This kind of error page is certainly not friendly to the end users, and Spring Boot prints this statement:

This application has no explicit mapping for /error, so you are seeing this as a fallback.

That means programmers should handle mapping for /error URL and provide custom, user-friendly error pages.

Spring Boot allows programmers to disable the white label error page by setting the following property in the application.properties file:

server.error.whitelabel.enabled=false

Then the raw error page provided by the server gets displayed, i.e. Tomcat like this:

tomcat internal server error

Anyway, we should provide custom error pages instead of the default ones which are very technical to the end users.

 

2. Use Custom Error Pages

Spring Boot makes it easy to override the default whitelabel error page. Just create the error.html page under the src/main/resources/templates directory. For example, with the following code:

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Error</title>
</head>
<body>
	<h3>Sorry, there was an error occurred!</h3>
</body>
</html>

Then when any error occurred, this custom error page will get displayed:

general custom error page

You can also provide custom error page for a specific HTTP status code (403, 404, 500, etc) – just by creating the 403.html (Forbidden error), 404.html (Page not found error), 500.html (Internal server error)… files under the templates/error directory (you must create error directory):

custome error pages in spring boot project

That’s it – very simple! Thanks to Spring Boot’s default configurations do all the details behind the scene.

 

3. Implement Custom Error Controller

In case you want to perform some tasks before the custom error pages get displayed, you can code a controller class implementing the ErrorController interface like this:

package net.codejava;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class CustomErrorController  implements ErrorController {

	@GetMapping("/error")
	public String handleError(HttpServletRequest request) {
		String errorPage = "error";	// default
		
		Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
		
		if (status != null) {
			Integer statusCode = Integer.valueOf(status.toString());
			
			if (statusCode == HttpStatus.NOT_FOUND.value()) {
				// handle HTTP 404 Not Found error
				errorPage = "error/404";
				
			} else if (statusCode == HttpStatus.FORBIDDEN.value()) {
				// handle HTTP 403 Forbidden error
				errorPage = "error/403";
				
			} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
				// handle HTTP 500 Internal Server error
				errorPage = "error/500";
				
			}
		}
		
		return errorPage;
	}
	
	@Override
	public String getErrorPath() {
		return "/error";
	}
}

Here, the getErrorPath() method returns a URL to which will be forwarded when an error occurs. And this error path is handled by the handler method right in this class. I showed you the code that returns the corresponding error page name based on HTTP status code, and you can add code to perform the logics you want to execute before the error pages get displayed.

Note that all exceptions are logged by Spring Boot by default, so you don’t have to log the errors again here in this custom controller class.

In case you want to handle specific exception classes rather than HTTP error code, follow this article: Spring Boot Controller-Based Exception Handler Examples

 

Conclusion

So far you have learned how to provide custom error pages in a Spring Boot application, and how to intercept the requests before those error pages get displayed. Again, Spring Boot makes error handling simple, easy and convenient. For reference, you can download the sample Spring Boot project attached below, and watch the following video to see the code in action:

 

Related Tutorials:

  • Spring Boot Controller-Based Exception Handler Examples
  • How to handle exceptions in Spring MVC

 

Other Spring Boot Tutorials:

  • Spring Boot automatic restart using Spring Boot DevTools
  • Spring Boot Form Handling Tutorial with Spring Form Tags and JSP
  • How to create a Spring Boot Web Application (Spring MVC with JSP/ThymeLeaf)
  • Spring Boot — Spring Data JPA — MySQL Example
  • Spring Boot Hello World RESTful Web Services Tutorial
  • How to use JDBC with Spring Boot
  • Spring Boot CRUD Web Application with JDBC — Thymeleaf — Oracle
  • Spring Boot RESTful CRUD API Examples with MySQL database
  • How to package Spring Boot application to JAR and WAR
  • Spring Boot Security Authentication with JPA, Hibernate and MySQL
  • Spring Data JPA Paging and Sorting Examples

 

About the Author:

Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.

Add comment

Понравилась статья? Поделить с друзьями:
  • Splendid does not support the current screen settings как исправить ошибку
  • Spn 520245 fmi 31 камаз 5490 ошибка
  • Spl error please use the proper driver ошибка
  • Spring bindingresult add error
  • Spn 520243 шакман ошибка