I have created a springboot application that contains some Rest API endpoints in .../api/myEndpoints... and thymeleaf templates for some UI forms the user can interact with.
Since I added an errorController:
@Controller
@RequestMapping("/error")
public class ErrorController {
@RequestMapping(method = RequestMethod.GET)
public String index(Model model) {
return "error";
}
}
whenever an exception is being thrown in my RestControllers, I receive an empty white website containing the word "error". This maybe makes sense for the web frontend, but not for my api. For the API I want spring to output the standard JSON result e.g.:
{
"timestamp": 1473148776095,
"status": 400,
"error": "Bad request",
"exception": "java.lang.IllegalArgumentException",
"message": "A required parameter is missing (IllegalArgumentException)",
"path": "/api/greet"
}
When I remove the index method from the ErrorController, then I always receive the JSON output. My question is: Is it somehow possible to exclude the automatic redirection to /error for all api urls (../api/*) only?
Thanks a lot.
There may be a better solution out there, until then... here's how you can achieve what you asked:
(1) Disable ErrorMvcAutoConfiguration
Add this to your application.properties
:
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
(2) Define two ControllerAdvices
Since we disabled ErrorMvcAutoConfiguration
, we need to catch the exception ourself. Create one advice to catch error for a specific package, and another advice to catch all other. They each redirect to a different url.
//Catch exception for API.
@ControllerAdvice(basePackageClasses = YourApiController.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class ErrorApiAdvice {
@ExceptionHandler(Throwable.class)
public String catchApiExceptions(Throwable e) {
return "/error/api";
}
}
//Catch all other exceptions
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public static class ErrorAdvice {
@ExceptionHandler(Throwable.class)
public String catchOtherExceptions() {
return "/error";
}
}
(3) create a controller to handle the error page
This is where you can have different logic in your error handling:
@RestController
public class MyErrorController {
@RequestMapping("/error/api")
public String name(Throwable e) {
return "api error";
}
@RequestMapping("/error")
public String error() {
return "error";
}
}
With Spring-Boot 1.4.x you can also implement ErrorViewResolver
(see this doc):
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
if("/one".equals(model.get("path"))){
return new ModelAndView("/errorpage/api");
}else{
return new ModelAndView("/errorpage");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With