Spring ошибка 404

You may extend the ResponseEntityExceptionHandler class, which include a lot of common exceptions in a Spring Boot Project. For example, if you wish to use a custom handler for binding exceptions, you may use the following,

@ControllerAdvice
public class MyApiExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    public ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String responseBody = "{\"key\":\"value\"}";
        headers.add("Content-Type", "application/json;charset=utf-8");
        return handleExceptionInternal(ex, responseBody, headers, HttpStatus.NOT_ACCEPTABLE, request);
    }
}

An other example for the http status 404-Not Found,

@ControllerAdvice
public class MyApiExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    public ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String responseBody = "{\"errormessage\":\"WHATEVER YOU LIKE\"}";
        headers.add("Content-Type", "application/json;charset=utf-8");
        return handleExceptionInternal(ex, responseBody, headers, HttpStatus.NOT_FOUND, request);
    }
}

Regarding the 404 not found exception you should configure the DispatcherServlet to throw and exception if it doesn’t find any handlers, instead of the default behavior. For issues with 404, you may also read this question.

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

This blog post provides a step-by-step guide on how to customize the 404 Not Found API response in Spring Boot using the NoHandlerFoundException. By creating a custom error response object and exception handler, you can provide more informative error messages to your API clients, improving their overall experience.

Introduction

When building a RESTful API using Spring Boot, developers may encounter a “404 Not Found” error when a client requests a resource that does not exist. In this case, the server does not have a handler to process the request, and it responds with a default error page. However, developers may want to customize the 404 response to provide more informative error messages to clients. Fortunately, Spring Boot provides a way to customize the 404 error response using the NoHandlerFoundException class.

Implementation

Step 1: Create a Custom Error Response Object

The first step in customizing the 404 error response is to create a custom error response object that will hold the error details. In this case, we will create a class called “ApiErrorResponse” with two fields: “code” to hold the error code and “message” to hold the error message.

public class ApiErrorResponse {

    private int code;
    private String message;

    public ApiErrorResponse(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public int getCode() {
        return code;
    }
}

ApiErrorResponse.java

In the example above, we’ve created a class called ApiErrorResponse with two fields, code, and message. We’ve also created a constructor that takes a code parameter to set the code field and a message parameter to set the message field. You can add more fields in the above class based on the details that you want to send to your API consumer like timestamp and so on.

Step 2: Create a Custom Exception Handler

The next step is to create a custom exception handler to handle the NoHandlerFoundException and return a JSON response with the custom error message.

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.NoHandlerFoundException;

@ControllerAdvice
public class ApiExceptionHandler {

    @ExceptionHandler({NoHandlerFoundException.class})
    public ResponseEntity<ApiErrorResponse> handleNoHandlerFoundException(
            NoHandlerFoundException ex, HttpServletRequest httpServletRequest) {
        ApiErrorResponse apiErrorResponse = new ApiErrorResponse(404, "Resource not found");
        return ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(MediaType.APPLICATION_JSON).body(apiErrorResponse);
    }
}

ApiExceptionHandler.java

In the example above, we’ve created a class called ApiExceptionHandler and annotated it with @ControllerAdvice.

We’ve created a method called handleNoHandlerFoundException(), which takes a NoHandlerFoundException parameter and returns a ResponseEntity with the custom error response object and HTTP status code.

Step 3: Add @EnableWebMvc Annotation

Add @EnableWebMvc annotation on top of your application main class or if you have any class annotated with @Configuration, you can add @EnableWebMvc annotation on top of that class.

Step 4: Update application.properties

The next step is to throw an exception if no handler mapping is found by adding the following code to your application.properties file:

spring.mvc.throw-exception-if-no-handler-found=true

application.properties

Step 5: Test Using Some Invalid URL

Test the changes by sending a request to your application using some invalid URL that does not exist.

curl --location 'localhost:8080/some/invalid/url'

shellscript

The below image shows how the customized error response will look like post the customization changes that we did inside the Spring Boot application.

Customized 404 Not Found Response

Customized 404 Not Found Response
Customized 404 Not Found Response

      Conclusion

      In this blog post, we learned how to customize the 404 Not Found API response using the NoHandlerFoundException class in Spring Boot. By following these steps, you can provide more informative error messages to your API clients and improve their overall experience.

      Bonus

      Curious to Learn Something New?

      Check out how to handle URL trailing slash changes in Spring Boot 3.

      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.

      Exception Handling in Spring MVC Example and Return Custom 404 Error Pages

      Exception Handling in Spring MVC is about handling exceptions in the application by using spring framework. Spring offers we can customized our error page to more friendly error page to user. This example provides the steps to write your own 404 Resource Not Found error page for your application.

      Here I am writing a custom exception for 404 error using the HttpStatus.NOT_FOUND. This will be annotated as the exception @ExceptionHandler in the controller. Whenever there is any error thrown on this type, it will be redirected to the configured error page.

      Popular Tutorials

      • Spring Tutorial
      • Spring MVC Web Tutorial
      • Spring Boot Tutorial
      • Spring Security Tutorial
      • Spring AOP Tutorial
      • Spring JDBC Tutorial
      • Spring HATEOAS
      • Microservices with Spring Boot
      • REST Webservice
      • Core Java
      • Hibernate Tutorial
      • Spring Batch

      Lets see the example.

      1. Controller in Application

      package com.doj.spring.web.controller;
      
      import java.util.HashMap;
      import java.util.Map;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.ModelMap;
      import org.springframework.web.bind.annotation.ExceptionHandler;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.servlet.ModelAndView;
      
      import com.doj.spring.web.bean.Student;
      import com.doj.spring.web.exception.StudentNotFoundException;
      
      @Controller
      public class WebController {
       
       static Map<String, Student> map = new HashMap<String, Student>();
       @RequestMapping("/")
       public String home(){
        Student student = new Student();
        student.setFname("Dinesh");
        student.setLname("Rajput");
        student.setAge("29");
        student.setAddress("Noida");
        student.setCourse("MS");
        map.put("1000", student);
        return "home";
       }
       
       @RequestMapping("/doj-student-{rollNumber}")
       public String dojStudentByRollNumber(ModelMap model, @PathVariable(value="rollNumber") String rollNumber){
        Student student = map.get(rollNumber);
        if (student == null) {
         throw new StudentNotFoundException("Student Not Found", "ERROR:404");
        }
        String name = student.getFname()+" "+student.getLname()+" "+student.getAddress()+" "+student.getCourse();
        model.put("name", name);
        return "home";
       }
       
       @ExceptionHandler(StudentNotFoundException.class)
       public ModelAndView handleStudentNotFoundException(StudentNotFoundException ex) {
        Map<String, StudentNotFoundException> model = new HashMap<String, StudentNotFoundException>();
        model.put("exception", ex);
        return new ModelAndView("student.error.400", model);
      
       }
       
       @ExceptionHandler(Exception.class)
       public ModelAndView handleException(Exception ex) {
        Map<String, Exception> model = new HashMap<String, Exception>();
        model.put("exception", ex);
        return new ModelAndView("student.error.500", model);
      
       }
      }
      
      
      

      2. Add Custom Exception

      package com.doj.spring.web.exception;
      
      import org.springframework.http.HttpStatus;
      import org.springframework.web.bind.annotation.ResponseStatus;
      
      @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Student Not Found")
      public class StudentNotFoundException extends RuntimeException{
      
       /**
        * 
        */
       private static final long serialVersionUID = -2581975292273282583L;
       
       String errorMessage;
       
       String errorCode;
      
       public StudentNotFoundException(String errorMessage, String errorCode) {
        super();
        this.errorMessage = errorMessage;
        this.errorCode = errorCode;
       }
      
       public String getErrorMessage() {
        return errorMessage;
       }
      
       public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
       }
      
       public String getErrorCode() {
        return errorCode;
       }
      
       public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
       }
       
      }
      
      

      3. Student Bean Class

      package com.doj.spring.web.bean;
      
      
      public class Student {
       
       String fname;
       
       String lname;
       
       String address;
       
       String course;
       
       String age;
       
       public String getFname() {
        return fname;
       }
       public void setFname(String fname) {
        this.fname = fname;
       }
       public String getLname() {
        return lname;
       }
       public void setLname(String lname) {
        this.lname = lname;
       }
       public String getAddress() {
        return address;
       }
       public void setAddress(String address) {
        this.address = address;
       }
       public String getCourse() {
        return course;
       }
       public void setCourse(String course) {
        this.course = course;
       }
       public String getAge() {
        return age;
       }
       public void setAge(String age) {
        this.age = age;
       }
       
      }
      
      

      4. Views JSP

      home.jsp

      View for Success Page

      <h1>${name} Welcome to DOJ Classes for Spring MVC!!!</h1>
      

      Error Page View
      400.jsp

      <h1>${exception.errorCode}  -  ${exception.errorMessage} !!!</h1>
      

      mainTemplate.jsp

      <!DOCTYPE h1 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <%@taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
      <html>
       <head>
        <title><tiles:insertAttribute name="title"/></title>
        <style>
            .error {
                color: red; font-weight: bold;
            }
        </style>
       </head>
       <body style="text-align: center;">
        <div id="header" style="height: 10%;background-color: gray;"><tiles:insertAttribute name="header"/></div>
        <div id="body" style="height: 70%; background-color: aqua;padding-top: 40px;"><tiles:insertAttribute name="body"/></div>
        <div id="footer" style="height: 10%;background-color: gray;"><tiles:insertAttribute name="footer"/></div>
       </body>
      </html>
      
      

      5. Spring Configurations based on Java Configuration

      package com.doj.spring.web.config;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.ViewResolver;
      import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
      import org.springframework.web.servlet.config.annotation.EnableWebMvc;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
      import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
      import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
      
      @Configuration
      @EnableWebMvc
      @ComponentScan(basePackages={"com.doj.spring.web.controller"})
      public class SpringWebConfiguration extends WebMvcConfigurerAdapter{
      
       @Bean
       public ViewResolver viewResolver() {
        return new TilesViewResolver();
       }
       
       @Bean
       public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tiles = new TilesConfigurer();
        tiles.setDefinitions(new String[] {
          "/WEB-INF/view/tiles/tiles-def.xml"
        });
        tiles.setCheckRefresh(true);
        return tiles;
       }
       
       //Configure for default static content handling
       @Override
       public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
       }
      }
      
      

      6. Deployment Descriptor based on java configuration

      package com.doj.spring.web;
      
      import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
      
      import com.doj.spring.web.config.SpringWebConfiguration;
      
      //this file is equivalent to web.xml
      public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
      
       //Configuration for non web components like services, daos, repos, etc.
       @Override
       protected Class<?>[] getRootConfigClasses() {
        return null;
       }
       
       //Specifying Spring MVC configuration class "SpringWebConfiguration.class" it equivalent to *-servlet.xml file
       @Override
       protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{SpringWebConfiguration.class};
       }
      
       //Mapping dispatcher server to "/" i.e. Servlet Mapping in the web.xml 
       @Override
       protected String[] getServletMappings() {
        return new String[]{"/"};
       }
      }
      
      

      All files related this example is not mention here for whole application you can download the zip of working application.

      SpringMVCExceptionHandlingExample

      7. Lets see demo this application

      1. Welcome Page

      http://localhost:8080/SpringMVCExceptionHandlingExample/

      Exception Handling in Spring MVC

      2. Error Page

      http://localhost:8080/SpringMVCExceptionHandlingExample/doj-student-10001

      Exception Handling in Spring MVC Example and Return Custom 404 Error Pages

      Spring MVC Related Posts

      • Spring MVC Web Tutorial
      • Spring MVC Interview Questions
      • MVC Design Pattern
      • Spring MVC DispatcherServlet
      • Spring MVC WebApplicationContext and Root Application Context
      • Spring MVC @Controller Annotation
      • Spring MVC @RequestMapping Annotation
      • Spring MVC @RequestParam Annotation
      • Spring MVC ContextLoaderListener
      • Spring MVC @RequestParam and @PathVariable annotations
      • Spring MVC Hello World Example
      • Spring MVC Exception Handling Example
      • Spring MVC with Hibernate CRUD Example
      • Spring MVC Tiles Plugin with Example
      • Spring MVC Interceptor with example
      • Spring MVC with MongoDB CRUD Example
      • Spring MVC Internationalization & Localization with Example

      About The Author

      Dinesh Rajput

      Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture.

      He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

      Понравилась статья? Поделить с друзьями:
    • Spring boot rest обработка ошибок
    • Spotify ошибка при запуске
    • Spotlight ошибка списка исключений
    • Spotify что то пошло не так ошибка
    • Spn 523613 fm1 16 камаз ошибка