You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么全局异常处理无法捕获Filter过滤器中抛出的异常?

异常无法被捕获的原因
  • @RestControllerAdvice 是Spring MVC提供的全局异常处理组件,生效范围仅限Spring Controller层抛出的异常。Filter属于Servlet层级的组件,执行顺序在DispatcherServlet之前,异常抛出时请求还未进入Spring MVC的处理链路,自然无法被Spring的全局异常处理器捕获。
  • Filter抛出的异常默认会被Tomcat、Undertow等Servlet容器直接接收,容器会直接走内置的错误页跳转逻辑,不会将异常传递到Spring的处理流程中。
可落地的解决方案

方案1:Filter内自行捕获异常写回响应

直接在doFilter方法外层增加try-catch,捕获异常后按照你期望的返回格式直接写入响应,和你全局异常处理的逻辑保持一致即可,示例代码:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
    try {
        String token = httpServletRequest.getHeader("token");
        if (token == null)
            throw new NoTokenException();

        String s = jwtToken.parseJwt(token);
        httpServletRequest.setAttribute("id", s);

        filterChain.doFilter(servletRequest, servletResponse);
    } catch (Exception e) {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.getWriter().write("msg");
        httpServletResponse.flushBuffer();
    }
}

方案2:转发异常到Spring错误处理端点

捕获异常后将请求转发到Spring Boot默认的错误处理路径/error,异常就会进入Spring的处理链路,你现有的全局异常处理器也可以正常捕获处理:

// 放在Filter的catch块中
catch (Exception e) {
    httpServletRequest.setAttribute("javax.servlet.error.exception", e);
    httpServletRequest.getRequestDispatcher("/error").forward(httpServletRequest, httpServletResponse);
}

内容的提问来源于stack exchange,提问作者user16836342

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:54:03