问题
定制网站过滤器中抛出异常,定制网站未经过全局异常处理器,定制网站前端未接收到异常信息。
问题分析
过滤器Filter和过滤器Interceptor定制网站的使用总是后端开发不定制网站可避免的一部分,定制网站有时候我们需要在过滤定制网站器或拦截器中进行逻辑处理,抛出异常,那么这里抛出的异常可以被@ControllerAdvice注释的异常处理类捕获吗?答案是Filter不会,而Interceptor可以,Filter是基于Servlet框架编写的,Interceptor是基于SpringMVC框架的,SpingMVC不会对Filter中的异常统一处理,所以这里被抛出的异常不能被捕获,那我们如何让不能被捕获的异常被被捕获呢?
解决措施
方法一:HandlerExceptionResolver
我们在要抛出异常的过滤器里面,引入HandlerExceptionResolver,直接抛出一个全局异常。
举例
我是要在JwtAuthorizationTokenFilter这个过滤器中抛出一个对Token异常的判断。
测试
效果
代码
@Autowired @Qualifier("handlerExceptionResolver") private HandlerExceptionResolver resolver; if( true) { resolver.resolveException(httpServletRequest, httpServletResponse, null,new BadRequestException(ResultEnum.TOKEN_EXPIRED)); return;//捕获异常后就直接退出了 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
方法二:把异常交给Controller处理
既然Filter中的异常,不能经过我们定义的异常处理类,那我们就把此异常交给controller,让controller经过异常处理类,帮我们处理。
步骤
- 定义过滤器,将异常交给controller处理
- 调整该过滤器的位置,将这个过滤器的位置要放在存在异常处理器的前面(原因看后面图解)
- 定义处理异常的controller
异常过滤器
public class ExceptionFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { chain.doFilter(request, response); } catch (Exception e) { request.setAttribute("exception", e); request.getRequestDispatcher("/error").forward(request, response); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
调整过滤器位置
@Beanpublic FilterRegistrationBean<ExceptionFilter> exceptionFilterRegistration() { FilterRegistrationBean<ExceptionFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new ExceptionFilter()); registration.setName("exceptionFilter"); /* 这个序号要很小,保证 exceptionFilter 是所有过滤器链的入口 */ registration.setOrder(Integer.MIN_VALUE); return registration;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
抛出异常的controller
@RestControllerpublic class MyErrorContorller { @PostMapping("/error") public Result throwException(HttpServletRequest request) throws Exception { throw (Exception) request.getAttribute("exception"); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Result 是我自己定义的结果处理类,你们用自己的即可
测试
结果
过滤器位置调整原因
方法三:ErrorController
没有看懂,后续看懂了文章补充
参考文章
参考博客1:
参考博客2:
说明
写这篇文章时,我正处于一个基本的学习阶段,好多知识的原理并不是很清晰,部分解释都是根据自己的想法,如果有错误的地方,欢迎大家批评指正,也欢迎大家在评论区交流。