Spring Boot @ControllerAdvice 异常处理程序未触发

Posted

技术标签:

【中文标题】Spring Boot @ControllerAdvice 异常处理程序未触发【英文标题】:Spring Boot @ControllerAdvice exception handler not firing 【发布时间】:2016-03-25 19:58:44 【问题描述】:

我设置了以下控制器建议,以针对错误条件返回 API 合同:

@ControllerAdvice
public class ExceptionHandler : ResponseEntityExceptionHandler()

    @ExceptionHandler(Throwable::class)
    @ResponseBody
    public fun onException(ex: Throwable): ResponseEntity<ErrorResponse>
    
        val errorResponse = ErrorResponse(
           response = ResponseHeader(ex.responseCode(), ex.message))
        return ResponseEntity(errorResponse, HttpStatus.UNAUTHORIZED);
    


工作正常,然后停止工作。现在所有异常都被路由到BasicErrorController,它返回如下格式:


  "timestamp" : 1450495303166,
  "status" : 403,
  "error" : "Forbidden",
  "message" : "Access Denied",
  "path" : "/profile/candidates"

以上是一个很好的固执己见的起点,但现在它不会妨碍你。

我尝试用ExceptionHandlerExceptionResolver 的一个实例替换错误处理程序,但没有奏效。 我尝试过制作自己的CustomErrorHandler,但这也不合适,因为当它重新路由到自定义错误控制器时,HttpServletRequest 中不再存在原始异常。需要此信息才能向客户端返回适当的响应。

我该怎么做:

使 SpringBoot 将异常转发到异常控制器。 恢复@ControllerAdvice 异常处理程序,这样我就可以返回适当的响应正文和状态代码。

关于启动 spring 日志:

main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in exceptionHandler
main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in responseEntityExceptionHandler

编辑:

在阅读了 Spring Boot 文档之后,我现在明白 BasicErrorController 应该只针对@ControllerAdvice 处理的任何异常触发。这似乎没有发生。那么问题是为什么?

【问题讨论】:

【参考方案1】:

我还有一个 Spring Security 过滤器,用于评估 API-Key 和 Access-Token 标头凭据。 @ControllerAdvice 在这里不起作用 - 很公平,因为我们没有处理控制器端点!

使用 EntryPoint 和 AcessDeniedHandler 处理来自安全过滤器的异常。里面有可以配置的:

.exceptionHandling()

如果您在过滤器中扩展 AbstractAuthenticationProcessingFilter,则配置 FailureHandler。

 setAuthenticationFailureHandler()

如果您将应用程序部署在应用服务器下,Afaik ErrorController 将被覆盖。

【讨论】:

我试过这个,但没有遵循。最终在我的回答中使用了这种方法。不知道好不好。

以上是关于Spring Boot @ControllerAdvice 异常处理程序未触发的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2Spring Boot CLI

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring Boot:Spring Boot启动原理分析