Springboot如何统一处理Filter异常
作者:QMCoder
这篇文章主要介绍了Springboot如何统一处理Filter异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Springboot统一处理Filter异常
由于Filter异常Spring MVC无法进行统一处理,所以需要手动处理一下异常
定义一个Filter
这个Filter位于所有Filter的最前面,当其他Filter发生异常,捕获异常栈,然后转发到ErrorController
@Slf4j public class ExceptionFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("ex filter init ......."); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 是否已经放有异常栈, 避免循环 boolean isRethrow = !Objects.isNull(request.getAttribute(Req.Attr.EX)); if (isRethrow) { chain.doFilter(request, response); return; } try { chain.doFilter(request, response); } catch (AbstractCustomException e) { // 发生异常,保存异常栈 request.setAttribute(Req.Attr.EX, e); request.getRequestDispatcher(UrlUtil.ERROR_RETHROW).forward(request, response); } } @Override public void destroy() { } }
注册Filter为第一个
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Bean public ExceptionFilter exceptionFilter() { return new ExceptionFilter(); } @Bean public FilterRegistrationBean registerExceptionFilter() { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(exceptionFilter()); bean.addUrlPatterns("/*"); bean.setOrder(1); return bean; }
ErrorController如下
@RestController public class ErrorController { @Resource private HttpServletRequest request; /** * 重新抛出异常 */ @RequestMapping("/error/rethrow") public void rethrow() { throw ((AbstractCustomException) request.getAttribute(Req.Attr.EX)); } }
ErrorController抛出的异常会被Spring的全局异常处理捕获
@Slf4j @ControllerAdvice public class GlobalExceptionHandler { /** * 登录异常处理 * @param e 异常 * @return 处理结果 */ @ExceptionHandler(LoginException.class) @ResponseBody public Result<String> loginExceptionHandler(LoginException e) { OperatorContext.remove(); log.error("登录异常", e); return Result.loginError(e.getMessage()); } /** * 业务异常处理 * @param e 异常 * @return 处理结果 */ @ExceptionHandler(BizException.class) @ResponseBody public Result<String> bizExceptionHandler(BizException e) { log.error("业务异常", e); return Result.error(e.getMessage()); } @ExceptionHandler(LawlessInvokeException.class) @ResponseBody public Result<String> lawlessException(LawlessInvokeException e) { log.error("@非法调用@", e); return Result.error(e.getMessage()); } /** * 全局异常处理 * @param e 异常 * @return 处理结果 */ @ExceptionHandler(Exception.class) @ResponseBody public Result<String> exceptionHandler(Exception e) { log.error("服务器异常", e); return Result.error("服务器异常"); }
这样我们就可以在Filter中和其他地方一样抛出异常了
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。