Spring Boot不显示实现自定义ErrorController的错误页面

时间:2019-05-09 14:20:14

标签: spring spring-boot spring-mvc error-handling thymeleaf

我试图根据HTTP状态代码显示自定义错误页面。我所做的是在ErrorController中实现Spring的CustomErrorController接口,但是似乎Spring Boot无法识别它。

我已按照本教程进行操作:https://www.baeldung.com/spring-boot-custom-error-page(第3.1节)。

我已经读到,首先,您需要摆脱著名的Spring默认的Whitelabel Error Page。所以我这样做了:

@SpringBootApplication(exclude = { ErrorMvcAutoConfiguration.class })
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

这似乎可行,因为不再出现Whitelabel错误页面,但是现在当发生错误时,出现Apache Tomcat错误页面(包括堆栈跟踪的丑陋页面)而不是我的。

然后我就这样实现了CustomErrorController

@Controller
@RequestMapping("/error")
public class CustomErrorController implements ErrorController {

    @RequestMapping
    public String handleError(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

        if (statusCode != null) {
            // Specific error page
            return "redirect:/error/" + statusCode;
        }

        // Global error page
        return "error/error";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @GetMapping("/404")
    public String notFoundErrorPage() {
        return "error/404";
    }

// Other error codes mapping methods

}

我正在使用Thymeleaf,并且错误视图位于src/main/resources/views/error下,其中每个特定的错误页面名称都遵循建议的<error_code>.html格式,因此,例如404错误将具有{{1 }}页面。

到目前为止,我对其他应用程序视图的解析没有任何问题。实际上,我已经配置了Spring Security以在发生访问被拒绝并且错误页面正确显示的情况下调用404.html端点。

/error/403也会发生同样的情况,发生内部服务器异常时会调用此方法,因为我还实现了以下/error/500方法:

@ControllerAdvice @ExceptionHandler

因此,如果这些端点中的每一个都单独工作,那么为什么如果Spring引发错误,@ControllerAdvice @Log4j2 public class GlobalDefaultExceptionHandler { @ExceptionHandler(Exception.class) public String defaultErrorHandler(Exception exception) throws Exception { if (AnnotationUtils.findAnnotation(exception.getClass(), ResponseStatus.class) != null) { throw exception; } log.catching(exception); return "redirect:/error/500"; } } 方法就永远不会被调用?

谢谢。

1 个答案:

答案 0 :(得分:1)

似乎您的GlobalDefaultExceptionHandler正在预先捕获所有异常。这就是为什么从未调用handleError的原因。

您的其他端点正常工作,因为您直接调用它们-正如您所描述的那样。

我建议使用@ControllerAdvice处理特定的异常,让您的CustomErrorController实现处理所有尚未处理的异常。春季启动会将它们包装在Http Status 500中的NestedServletException内。您可以使用以下方法在handleError内找到根本原因:

Object exception = request.getAttribute("javax.servlet.error.exception");
    if (String.valueOf(exception) != null) {
        log.info("Nested Exception: " + String.valueOf(exception));
    }

检查这些答案以获取有关订购以及Spring Boot中错误工作流程的更多信息:

order

spring boot error handling flow