1

I need to override the spring boot default error page. I injected the WebServerFactoryCustomizer bean and specified the corresponding error page. This works correctly in the spring boot embedded tomcat, but it still jumps to spring boot's default error page when I deploy to external tomcat. Is it missing from my configuration? Thanks for any help :)

here is the codes:

ErrorConfig.java

 @Configuration
public class ErrorConfig {

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> sessionManagerCustomizer() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        return server -> {
            ErrorPage error400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
            ErrorPage error500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
            ErrorPage error404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
            ErrorPage error403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
            ErrorPage error503 = new ErrorPage(HttpStatus.SERVICE_UNAVAILABLE, "/error/503");
            server.addErrorPages(error400, error500, error404, error403, error503);
        };
    }
}

ErrorController.java

@Controller
public class ErrorController {

    @RequestMapping(value = "/error/{code}")
    public String error(@PathVariable int code, Model model) {
        String page = "/error/error";
        switch (code) {
            case 403:
                model.addAttribute("code", 403);
                page = "/error/403";
                break;
            case 404:
                model.addAttribute("code", 404);
                page = "/error/404";
                break;
            case 500:
                model.addAttribute("code", 500);
                page = "/error/500";
                break;
            case 503:
                model.addAttribute("code", 503);
                page = "/error/503";
                break;
            default:
                model.addAttribute("code", 404);
                page = "/error/404";
        }
        return page;
    }

}

pom.xml(part of)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
Aezio
  • 203
  • 5
  • 18
  • Are you omitting `spring-boot-starter-tomcat` when you're deploying to another tomcat? As I understand it, that starter is only for the embedded tomcat. You should exclude it if you're not using it. – Paul Hicks Jun 21 '18 at 02:44
  • Actually, [this answer](https://stackoverflow.com/a/32081889/3195526) seems to cover your use case. I've learned something new :) – Paul Hicks Jun 21 '18 at 02:46

1 Answers1

0

As per my understanding, neither TomcatServletWebServerFactory nor WebServerFactoryCustomizer will work in external tomcat container especially when the scope of spring-boot-starter-tomcat is provided. I think you can use @ExceptionHandler annotation and ErrorController interface to redirect the request to the page(eg. 404/500 etc.) which you want. For example

@RestController
@ControllerAdvice
public class ExceptionController implements ErrorController {
    private static final String ERROR_PATH = "/error";

    @RequestMapping(value = "/error/{code}")
    public String handleError(@PathVariable int code) {
        String rtn = null;
        switch (code) {
            case 404:
                rtn = "Page not found";
                break;
            case 500:
                rtn = "Internal server error";
                break;
            default:
                rtn = "error";
                break;
        }
        return rtn;
    }

    @RequestMapping(value = ERROR_PATH)
    public void handleError(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect("error/404");
    }

    /**
     * implement ErrorController to handle 404
     */
    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }

    @ExceptionHandler(Exception.class)
    public void handleException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        response.sendRedirect("error/500");
    }
}
Anonymity
  • 61
  • 1
  • 7