0

I need to have a controller (or other component) that handles all 404 errors and smartly redirects to the correct page (this is based on a table src/ target). I have found a few questions about handling thrown exceptions FROM controllers so I have made the following:

@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Throwable.class)
    @ResponseBody
    ResponseEntity<String> handleControllerException(HttpServletRequest req, Throwable ex) {

        String slug = req.getRequestURI(); // this is the URL that was not found
        URI location=null;
        try {
            // lookup based on slug ...
            location = new URI("http://cnn.com"); // let's say I want to redirect to cnn
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setLocation(location);
        return new ResponseEntity<String>("Page has permanently moved", responseHeaders, HttpStatus.PERMANENT_REDIRECT);


    }
}

I have not made any other configuration changes

The two issues with this are:

  • It only catches exceptions thrown by my other controllers and not 404 errors
  • It catches ALL types of exceptions and not just 404

Any ideas on how to implement a kind of "catch-all"?

checklist
  • 12,340
  • 15
  • 58
  • 102

1 Answers1

0

This is probably not the best Spring boot solution, but maybe a similar idea can be extrapolated from it and applied to your application. I had a similar problem when working with Spring 3.x, and here's the solution I came up with.

My scenario was that I had multiple servlets running under the same application context. One of those handled a web interface, and another one handled API calls. I wanted the servlet handling the API calls to handle 404s differently than the UI servlet.

I created a new class which extended DispatcherServlet, and overridden the noHandlerFound method. I wired my new class in my web.xml in the <servlet>tags instead of the default DispatcherServlet class I had there before.

<servlet>
    <servlet-name>api-servlet</servlet-name>
    <servlet-class>path.to.your.new.DispatcherServletClass</servlet-class>
    ...
</servlet>
brnt
  • 11
  • 2