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

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

我正在尝试根据 HTTP 状态代码显示自定义错误页面。我所做的是实现 Spring 的 ErrorController CustomErrorController 中的接口(interface)但似乎 Spring Boot 没有识别它。

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

我已经读过,首先你需要摆脱著名的 Spring 的默认 Whitelabel 错误页面。所以我这样做了:

@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,我的错误 View 位于 src/main/resources/views/error 下,其中每个特定的错误页面名称都遵循 <error_code>.html 的推荐格式因此,例如,404 错误将具有 404.html关联的页面。

到目前为止,我在解决其他应用程序 View 方面没有任何问题。实际上,我已将 Spring Security 配置为调用 /error/403如果发生访问被拒绝并且错误页面正确显示,则端点。
/error/500 也是如此,当发生内部服务器异常时调用它,因为我还实现了以下 @ControllerAdvice @ExceptionHandler方法:

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

因此,如果这些端点中的每一个都单独工作,为什么如果 Spring 抛出错误 handleError方法没有被调用过吗?

谢谢你。

最佳答案

好像你的 GlobalDefaultExceptionHandler正在预先捕获每个异常。这就是为什么handleError永远不会被调用。

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

我建议使用 @ControllerAdvice处理特定异常让您的CustomErrorController实现处理所有尚未处理的异常。 Spring Boot 会将它们包裹在 NestedServletException 内使用 Http Status 500。您可以在 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

关于Spring Boot 不显示实现自定义 ErrorController 的错误页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56061542/

相关文章:

spring - 如何为使用 Spring 实现的 RESTful 服务生成 Java 客户端代理?

java - 当异步方法中某个线程发生异常时终止所有线程

spring-boot - 无法连接到 Eureka 服务器 - Spring Boot | Eureka | docker

java - SpringBoot应用程序中的主类

java - Hibernate - 如何根据另一个对象的属性对结果进行排序

java - Struts2 排除模式 - 它到底是如何工作的?

spring - Gradle 和 SLF4J 拒绝排除传递依赖项会导致 IllegalStateException

spring - Spring Boot JPA 中的全文搜索

java - Spring 3.2/hibernate 4.1.9 : Use of @OneToMany or @ManyToMany targeting an unmapped class error

java - Spring HandlerInterceptor 调用了两次