3

I've managed to build static error pages and redirect to them with this bean:

    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {

        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                if (optiuniEnvironment.equals("development")) {
                    ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
                    ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
                    ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/404.html");

                    container.addErrorPages(error401Page, error404Page, error500Page);
                }
            }
        };
    }

However, now I want to build a custom page, that uses the functionality of the controller.

So in my controller I have something like

    @RequestMapping("/404.html")
    String pageNotFound(Model model, HttpServletRequest request)
    {
        return "404";
    }

and wish to redirect to it if I encounter the HttpStatus 404.

I believe the answer is configuring the DispatcherServlet, but not sure. Any ideas? Thanks!

(if possible, please use java-based configurations, not xml)

2
  • Why not implementing Exception handler, if you are using spring? Commented May 18, 2017 at 14:19
  • That's pretty much the question. What (and maybe how) to use. I'll take a look at exception handler. Commented May 18, 2017 at 14:31

2 Answers 2

6

You can handle these error using following methods:

  1. Using Exception Handler method in same controller:

@ExceptionHandler(NoHandlerFoundException.class)
public String handle404Exception(NoHandlerFoundException ex) {
     //do whatever you want
     return "viewName";
}
  1. Create Exception controller

@ControllerAdvice
public class ExceptionController {

    @ExceptionHandler(NoHandlerFoundException.class)
    public String handle404Exception(NoHandlerFoundExceptionex) {
         //do whatever you want
         return "viewName";
    }
}

If using Spring Boot, set following properties in application.properties

server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
  1. Adding Error Page Registrar:

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
    return new CustomErrorPageRegistrar();
}

private static class CustomErrorPageRegistrar implements ErrorPageRegistrar {

    // Register your error pages and url paths.
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }

}

and define your controller endpoint for respective urls (eg. /400)

Sign up to request clarification or add additional context in comments.

3 Comments

I assume your solution works, however I am using spring boot 1.2.0.RELEASE and cannot update now, so this property is not available. Still, thanks for the input.
@Irikos check the third option(added it now), it might work!
Hey Afridi, I tried the first two solutions and did not work (I was unable to use the resource.add-mappings=false property though, as it ruined my entire app). It did not redirect me to the classic whitelabel page, but did not redirect me to the custom one either. For the 3rd one I believe spring boot spring boot 1.4 is needed (I have 1.2). Still, inspired from this, I found a solution, even if not the best. I'll post it soon.
2

Solution for SpringBoot version: 1.2 - even if not the best - it's good enough for now.

Created a GlobalErrorController

@RestController
@Profile("prod")
public class GlobalErrorController implements ErrorController {

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public void error(HttpServletResponse response) throws IOException {
        int status = response.getStatus();
        switch (status) {
            case 404:
                response.sendRedirect("/404");
                break;
            case 401:
                response.sendRedirect("/401");
                break;
            case 403:
                response.sendRedirect("/401");
                break;
            default:
                response.sendRedirect("/404");
        }

    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

And in my HomeController I added:

@RequestMapping("404")
String get404ErrorPage() {
    return "404";
}

@RequestMapping("401")
String get401ErrorPage() {
    return "401";
}

I chose this approach because I need in the error pages some functionality from the controller.

Other solutions are more than welcome!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.