一尘不染

如何管理Spring中过滤器中引发的异常?

spring

我想使用通用方式来管理5xx错误代码,特别是当整个Spring应用程序中的db关闭时。我想要一个漂亮的错误json而不是堆栈跟踪。

对于控制器,我有一个@ControllerAdvice针对不同异常的类,这也捕获了db在请求中间停止的情况。但这并不是全部。我也碰巧有一个自定义CorsFilter扩展名OncePerRequestFilter,在那里,当我打电话给doFilter我时CannotGetJdbcConnectionException,它将不受的管理@ControllerAdvice。我在网上阅读了几件事,这只会让我更加困惑。

所以我有很多问题:

  • 我是否需要实施自定义过滤器?我找到了,ExceptionTranslationFilter但这只能处理AuthenticationExceptionAccessDeniedException
  • 我想实现自己的实现HandlerExceptionResolver,但这使我感到怀疑,我没有任何自定义异常要管理,必须有比这更明显的方法。我还尝试添加一个try / catch并调用的实现HandlerExceptionResolver(应该足够好,我的例外没有什么特别的),但这在响应中不返回任何内容,我得到一个状态200和一个空主体。
    有什么好办法解决这个问题吗?谢谢

阅读 763

收藏
2020-04-12

共1个答案

一尘不染

这就是我所做的:

我在这里阅读了有关过滤器的基础知识,并且发现需要创建一个自定义过滤器,该过滤器将首先出现在过滤器链中,并且将尝试捕获所有可能在此发生的运行时异常。然后,我需要手动创建json并将其放入响应中。

所以这是我的自定义过滤器:

public class ExceptionHandlerFilter extends OncePerRequestFilter {

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } catch (RuntimeException e) {

            // custom error response class used across my project
            ErrorResponse errorResponse = new ErrorResponse(e);

            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            response.getWriter().write(convertObjectToJson(errorResponse));
    }
}

    public String convertObjectToJson(Object object) throws JsonProcessingException {
        if (object == null) {
            return null;
        }
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }
}

然后我在之前将其添加到web.xml中CorsFilter。而且有效!

<filter> 
    <filter-name>exceptionHandlerFilter</filter-name> 
    <filter-class>xx.xxxxxx.xxxxx.api.controllers.filters.ExceptionHandlerFilter</filter-class> 
</filter> 


<filter-mapping> 
    <filter-name>exceptionHandlerFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<filter> 
    <filter-name>CorsFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
2020-04-12