I am using @ControllerAdvice to do exception handling globally. but I want to return the exception in Json format if the request is ajax(xhr) and if it's not I want to show my exception as html.
so the response type is dynamic. it might be html or json. And I am using thymleaf to generate my html pages.
how can I do that in spring boot?
@ResponseBody
@ExceptionHandler(Exception.class)
public ModelAndView handle(Exception exception, WebRequest request) {
this.logException(exception, request);
var model = getErrorPageModel(exception);
return new ModelAndView("exception", model, HttpStatus.OK);
}
Step 1: Determine which type of view you want
From the
WebRequest, you have to retrieve the necessary information to either return JSON or HTML. One possible way of doing so is by parsing theAcceptheader:A better alternative is to use Spring's
ContentNegotiationManagerby autowiring it into your controller advice:By default, Spring Boot's
ContentNegotiationManagerwill do exactly the same as the original code, but this can be extended with other strategies.Be aware that the
resolveMediaTypes()method requires aNativeWebRequest. So you have to change the type of therequestparameter.Step 2: Implement the model + view
Now what you have to do is implement the model and view for both the HTML and JSON view.
For the HTML view, you can use a Thymeleaf template, for example
error.html:After that, you can return the following
ModelAndViewfrom your exception handler:For the JSON part, you can use the
MappingJackson2JsonViewview class:This requires an
ObjectMapper, which you can autowire into your controller advice.Everything combined you get: