SpringBoot 使用 ControllerAdvice 中的自定义错误处理所有错误

Posted

技术标签:

【中文标题】SpringBoot 使用 ControllerAdvice 中的自定义错误处理所有错误【英文标题】:SpringBoot handle all errors with custom error in ControllerAdvice 【发布时间】:2020-10-27 12:13:07 【问题描述】:

我有一个 REST api spring boot 应用程序,想处理 ControllerAdvice 中的任何错误,因为我想有一个自定义的响应格式,而不是使用 Spring 默认响应。

例如,像 RequestRejectedException 这样的异常不是通过控制器建议处理的。有没有一种优雅的方法来处理 Spring 上的一个处理程序中的任何可能的错误?

对于 RequestRejectedException,我已经实现了 GenericFilterBean 并在那里重新格式化了响应,但希望有一种更统一的方式来处理所有错误。

【问题讨论】:

【参考方案1】:

使用 ControllerAdvice 类似:

@ControllerAdvice
class GenericExceptionHandling extends ResponseEntityExceptionHandler 

    @ExceptionHandler(value = RuntimeException.class)
    protected ResponseEntity<Object> handleConflict(
      RuntimeException ex, WebRequest request) 
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, 
          new HttpHeaders(), HttpStatus.CONFLICT, request);
    


应该是有道理的,但由于这个异常在 spring 抛出的方式不同,它似乎不能这样处理。阅读related。因此,处理此问题的一种方法是使用最高阶过滤器,并在该过滤器中捕获此异常并将响应转换为您想要的响应。

*** 相关线程:Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized

【讨论】:

【参考方案2】:

Controller Advice 能够处理由控制器方法调用启动的任何流引发的任何异常。

这是“Spring MVC”处理异常的通用方式。

现在 Spring MVC 的基础架构在技术上基于单个 servlet(称为 DispatcherServlet),它可以通过 url、http 方法等将控制器方法“分配”给调用。

但是,您可以使用 Servlet 的过滤器,这些过滤器由底层 Web 容器(如 tomcat 或 jetty)直接部署和处理。因此,如果该代码引发了异常,它对于 Spring MVC 来说是“看不见的”,它甚至不会到达 MVC 控制器,因此控制器建议无法拦截异常。

您尚未指定确切源自 RequestRejectedException 的代码,但这可能是在 spring mvc 之外完成的,因此控制器建议不适用...

【讨论】:

以上是关于SpringBoot 使用 ControllerAdvice 中的自定义错误处理所有错误的主要内容,如果未能解决你的问题,请参考以下文章

视图控制器传值

iOS:检测触地、segue、触地

更改单个 ASP.NET Core 控制器的 JSON 序列化设置

覆盖angularjs

使用 Grails 3 配置 CORS

iOS工作笔记