Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - Error Controller to handle either JSON or HTML

I have a spring boot application.

I have a custom error controller, that is mapped to using ErrorPage mappings. The mappings are largely based on HTTP Status codes, and normally just render a HTML view appropriately.

For example, my mapping:

@Configuration
class ErrorConfiguration implements EmbeddedServletContainerCustomizer {

  @Override public void customize( ConfigurableEmbeddedServletContainer container ) {
      container.addErrorPages( new ErrorPage( HttpStatus.NOT_FOUND, "/error/404.html" ) )
  }

And my error controller:

@Controller
@RequestMapping
public class ErrorController {

    @RequestMapping( value = "/error/404.html" )
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public String pageNotFound( HttpServletRequest request ) {
        "errors/404"
    }

This works fine - If I just enter a random non-existent URL then it renders the 404 page.

Now, I want a section of my site, lets say /api/.. that is dedicated to my JSON api to serve the errors as JSON, so if I enter a random non-existent URL under /api/.. then it returns 404 JSON response.

Is there any standard/best way to do this? One idea I tried out was to have a @ControllerAdvice that specifically caught a class of custom API exceptions I had defined and returned JSON, and in my standard ErrorController checking the URL and throwing an apprpriate API exception if under that API URL space (but that didn't work, as the ExceptionHandler method could not be invoked because it was a different return type from the original controller method).

Is this something that has been solved?

like image 592
rhinds Avatar asked Apr 17 '15 15:04

rhinds


1 Answers

The problem was my own fault. I was trying to work out why my @ExceptionHandler was not able to catch my exception and return JSON - As I suggested at the end of my question, I thought I was having problems because of conflicting return types - this was incorrect.

The error I was getting trying to have my exception handler return JSON was along the lines of:

  "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
  "message": "Could not find acceptable representation"

I did some more digging/experimenting to try to narrow down the problem (thinking that the issue was because I was in the Spring error handling flow and in an ErrorController that was causing the problem), however the problem was just because of the content negotiation stuff Spring does.

Because my errorPage mapping in the web.xml was mapping to /error/404.html, Spring was using the suffix to resolve the appropriate view - so it then failed when I tried to return json.

I have been able to resolve the issue by changing my web.xml to /error/404 or by turning off the content negotiation suffix option.

like image 135
rhinds Avatar answered Oct 17 '22 15:10

rhinds