【问题记录】【SpringBoot】Filter中抛出的异常不会走RestControllerAdvice全局异常捕获

1  问题现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//如下是我定义的全局异常捕获@RestControllerAdvice
public class RestExceptionHandler {
    /**
     * 默认全局异常处理。
     * @param e the e
     * @return ResultDto
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultDto<String> exception(Exception e) {
        ResultDto<String> resultDto = new ResultDto<>();
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        if (handleExceptionControl(e, resultDto)) {
            return resultDto;
        }
        resultDto.setCode(ResultCodeEnum.ERROR.getCode());
        resultDto.setMsg(e.getMessage());
        return resultDto;
    }
}
//这个是我定义的FIlter 用于校验用户是否登录
@Slf4j
public class SsoTokenFilter extends HttpServlet implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;
        try {
             
        } catch (Exception e) {
            throw e;//不会走advice
        }
    }
}

2  原因分析

请求进来,会按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的顺序调用

当controller返回异常 也会按照controller -> aspect -> controllerAdvice -> interceptor -> filter来依次抛出

所以我们的Filter抛出的异常不会走advice,这是我们可以通过HandlerExceptionResolver来转换我们的异常。

3  解决办法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//自定义注解 引入SSO 登录校验Filter@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(SsoConfig.class})
public @interface EnableSsoLogin {
}
 
@Slf4j
public class SsoConfig implements DisposableBean {
 
    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;
 
    @Bean
    public FilterRegistrationBean ssoFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setName("SsoTokenFilter");
        registration.setOrder(1);
        registration.addUrlPatterns("/*");
        SsoTokenFilter ssoTokenFilter = new SsoTokenFilter(resolver);
        registration.setFilter(ssoTokenFilter);
        return registration;
    }
     
}
 
@Slf4j
public class SsoTokenFilter extends HttpServlet implements Filter {
    private HandlerExceptionResolver resolver;
    public SsoTokenFilter(HandlerExceptionResolver resolver) {
        this.resolver = resolver;
    }
 
     @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;
        try {
        //todo
        } catch(Exception e) {
             resolver.resolveException(req, res, null, e);
        }         
     }
}    

  

 


posted @   酷酷-  阅读(896)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示