Spring boot 404 error custom error response ReST
Solution 1
For those Spring Boot 2 users who don't wanna use @EnableWebMvc
application.properties
server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
ControllerAdvice
@RestControllerAdvice
public class ExceptionResolver {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public HashMap<String, String> handleNoHandlerFound(NoHandlerFoundException e, WebRequest request) {
HashMap<String, String> response = new HashMap<>();
response.put("status", "fail");
response.put("message", e.getLocalizedMessage());
return response;
}
}
Solution 2
It is worked for me in case of @RestControllerAdvice with spring boot
spring.mvc.throw-exception-if-no-handler-found=true
server.error.whitelabel.enabled=false
spring.resources.add-mappings=false
@RestControllerAdvice
public class ErrorHandlerController {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND )
public String handleNotFoundError(NoHandlerFoundException ex) {
return "path does not exists";
}
}
Solution 3
I've provided the sample solution on how to override response for 404 case. The solution is pretty much simple and I am posting sample code but you can find more details on the original thread: Spring Boot Rest - How to configure 404 - resource not found
First: define Controller that will process error cases and override response:
@ControllerAdvice
public class ExceptionHandlerController {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(value= HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorResponse requestHandlingNoHandlerFound() {
return new ErrorResponse("custom_404", "message for 404 error code");
}
}
Second: you need to tell Spring to throw exception in case of 404 (could not resolve handler):
@SpringBootApplication
@EnableWebMvc
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
}
Solution 4
Summing up all answers and comment, I think the best way to do this is-
First, tell spring boot to throw exception in case of no handler found in application.properties
spring.mvc.throw-exception-if-no-handler-found=true
Then handle NoHandlerFoundException
in your application. I handle this by following way
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
public void handleNotFoundError(HttpServletResponse response, NoHandlerFoundException ex) {
ErrorDto errorDto = Errors.URL_NOT_FOUND.getErrorDto();
logger.error("URL not found exception: " + ex.getRequestURL());
prepareErrorResponse(response, HttpStatus.NOT_FOUND, errorDto);
}
}
If you are using Swagger then you can view my other answer to exclude swagger URL from this exception handler
Solution 5
404 error is handled by DispatcherServlet. there is a property throwExceptionIfNoHandlerFound, which you can override.
In Application class you can create a new bean:
@Bean
DispatcherServlet dispatcherServlet () {
DispatcherServlet ds = new DispatcherServlet();
ds.setThrowExceptionIfNoHandlerFound(true);
return ds;
}
...and then catch the NoHandlerFoundException exception in
@EnableWebMvc
@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler
@ResponseStatus(value=HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorMessageResponse requestHandlingNoHandlerFound(final NoHandlerFoundException ex) {
doSomething(LOG.debug("text to log"));
}
}
Related videos on Youtube
Markus
Updated on March 08, 2022Comments
-
Markus about 2 years
I'm using Spring boot for hosting a REST API. Instead of having the standard error response I would like to always send a JSON response even if a browser is accessing the URL and as well a custom data structure.
I can do this with @ControllerAdvice and @ExceptionHandler for custom exceptions. But I can't find any good ways of doing this for standard and handled errors like 404 and 401.
Are there any good patterns of how to do this?
-
Opal almost 9 yearsMarkus, does my answer solve the problem? If so, please accept it.
-
-
Markus almost 9 yearsTrue, but in this case I'm interested in the 401 and 404 cases in order to be able to have one common error response for all errors to the clients. I don't want to have different structures of error response and as well never respond with anything other than for example JSON.
-
Markus almost 9 yearsYes, but in this case a html error is not suitable due to only rest clients are used.
-
Opal almost 9 yearsThe structure I presented is the default JSON error response structure. If you need only 401 or 404 just add appropriate exceptions instead of
MethodArgumentNotValidException
and change the method body. -
zbstof almost 7 yearsOr use spring.mvc.throw-exception-if-no-handler-found=true property instead of a custom DispatcherServlet bean
-
Reema over 6 yearsIs there any way to do this without using the annotation
@EnableWebMvc
I dont want to enable Web MVC -
Reema over 6 yearsIs there any way to do this without using the annotation
@EnableWebMvc
I dont want to enable Web MVC -
Ace Eusebio about 6 yearsHi @Reema! Were you able to do it without
@EnableWebMvc
? I would want to do it without it as well. -
Reema about 6 yearsNo, I haven’t got any solution for this yet!
-
Steve almost 5 yearsDoesn't work.
java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.servlet.NoHandlerFoundException]
-
ptrckdev about 4 yearsWhat are reason to not use @EnableWebMvc ?
-
fightlight about 4 years
-
RomanMitasov over 3 years
spring.resources.add-mappings=false
disabled swagger-ui in my service. Is there some workarounds for that? -
Jonas Pedersen about 2 yearsProperties needed in Spring 2.6.x is:
spring.mvc.throw-exception-if-no-handler-found=true spring.web.resources.add-mappings=false