基于控制器的错误页面 spring thymeleaf

Controller based error pages spring thymeleaf

我已经成功地构建了静态错误页面并使用这个 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);
                }
            }
        };
    }

但是,现在我想构建一个使用控制器功能的自定义页面。

所以在我的控制器中我有类似

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

并希望在遇到 HttpStatus 404 时重定向到它。

我相信答案是配置 DispatcherServlet,但不确定。 有任何想法吗?谢谢!

(如果可能,请使用基于 java 的配置,而不是 xml)

您可以使用以下方法处理这些错误:

  1. 在同一控制器中使用异常处理程序方法:

@ExceptionHandler(NoHandlerFoundException.class)
public String handle404Exception(NoHandlerFoundException ex) {
     //do whatever you want
     return "viewName";
}
  1. 创建异常控制器

@ControllerAdvice
public class ExceptionController {

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

如果使用 Spring 引导,请在 application.properties

中设置以下属性
server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
  1. 添加错误页面注册器:

@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"));
    }

}

并为相应的 url(例如 /400)定义您的控制器端点

SpringBoot 版本的解决方案:1.2 - 即使不是最好的 - 现在也足够好了。

创建了一个 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;
    }
}

在我的 HomeController 中我添加了:

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

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

我选择这种方法是因为我需要在错误页面中使用控制器的一些功能。

我们非常欢迎其他解决方案!