如何管理 Spring 过滤器中抛出的异常? [英] How to manage exceptions thrown in filters in Spring?

查看:42
本文介绍了如何管理 Spring 过滤器中抛出的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用通用方式来管理 5xx 错误代码,让我们具体说一下当整个 Spring 应用程序中 db 关闭时的情况.我想要一个漂亮的错误 json 而不是堆栈跟踪.

I want to use generic way to manage 5xx error codes, let's say specifically the case when the db is down across my whole spring application. I want a pretty error json instead of a stack trace.

对于控制器,我有一个用于不同异常的 @ControllerAdvice 类,这也捕获了数据库在请求中间停止的情况.但这并不是全部.我也碰巧有一个自定义 CorsFilter 扩展 OncePerRequestFilter 并且当我调用 doFilter 时,我得到 CannotGetJdbcConnectionException 和它不会由 @ControllerAdvice 管理.我在网上读了几件事,这让我更加困惑.

For the controllers I have a @ControllerAdvice class for the different exceptions and this is also catching the case that the db is stopping in the middle of the request. But this is not all. I also happen to have a custom CorsFilter extending OncePerRequestFilter and there when i call doFilter i get the CannotGetJdbcConnectionException and it will not be managed by the @ControllerAdvice. I read several things online that only made me more confused.

所以我有很多问题:

  • 我需要实现自定义过滤器吗?我找到了 ExceptionTranslationFilter 但这只能处理 AuthenticationExceptionAccessDeniedException.
  • 我想实现我自己的HandlerExceptionResolver,但这让我怀疑,我没有任何自定义异常要管理,一定有比这更明显的方法.我还尝试添加一个 try/catch 并调用 HandlerExceptionResolver 的实现(应该足够好,我的异常没什么特别的)但这在响应中没有返回任何内容,我得到状态 200和一个空的身体.
  • Do i need to implement a custom filter? I found the ExceptionTranslationFilter but this only handles AuthenticationException or AccessDeniedException.
  • I thought of implementing my own HandlerExceptionResolver, but this made me doubt, I don't have any custom exception to manage, there must be a more obvious way than this. I also tried to add a try/catch and call an implementation of the HandlerExceptionResolver (should be good enough, my exception is nothing special) but this is not returning anything in the response, i get a status 200 and an empty body.

有什么好的办法可以解决吗?谢谢

Is there any good way to deal with this? Thanks

推荐答案

所以这就是我所做的:

我在这里阅读了有关过滤器的基础知识,我发现我需要创建一个自定义过滤器将位于过滤器链中的第一个,并且将有一个 try catch 来捕获可能在那里发生的所有运行时异常.然后我需要手动创建 json 并将其放入响应中.

I read the basics about filters here and I figured out that I need to create a custom filter that will be first in the filter chain and will have a try catch to catch all runtime exceptions that might occur there. Then i need to create the json manually and put it in the response.

这是我的自定义过滤器:

So here is my custom filter:

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);
    }
}

然后我在 CorsFilter 之前将它添加到 web.xml 中.它有效!

And then i added it in the web.xml before the CorsFilter. And it works!

<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>

这篇关于如何管理 Spring 过滤器中抛出的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆