【问题记录】【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); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了