美文网首页
springboot 全局捕获异常无法捕获Filter中异常

springboot 全局捕获异常无法捕获Filter中异常

作者: Geroge1226 | 来源:发表于2021-03-09 10:49 被阅读0次

1、背景说明

小程序项目中,使用Filter对用户身份认证,用户未登录时,抛出系统自定义异常,系统中有使用全局捕获异常对自定义异常做处理。才测试时候,发现全局异常未生效。经过查询资料,知道其中问题点。

【代码示例:】

  • 全局捕获异常
@Component
@ControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    @Qualifier("configMessage")
    private MessageSource msgSource;

    @ResponseBody
    @ExceptionHandler(CustomException.class)
    public UniformResultTemplate<Object> handleCustomException(CustomException customException) {
        if (customException == null) {
            return new UniformResultTemplate<>(Code.SYS_ERROR.getCode(), Code.SYS_ERROR.getDesc());
        }
        String code = StringUtils.isEmpty(customException.getCode()) ? Code.FAIL.getCode():customException.getCode();
        return new UniformResultTemplate<>(code, getMessage(customException.getMsg()));
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public UniformResultTemplate<Object> handleCustomException(Exception e) {
        e.printStackTrace();
        if (e instanceof CustomException) {
            CustomException exception = (CustomException) e;
            return new UniformResultTemplate<>(exception.getCode(), exception.getMsg());
        }
        return new UniformResultTemplate<>(Code.SYS_ERROR.getCode(), Code.SYS_ERROR.getDesc());
    }
   // 配置国际化翻译
    public String getMessage(String message){
        String str = "";
        try{
            str = msgSource.getMessage(message,null, LocaleContextHolder.getLocale());
        }catch (Exception e){
            return message;
        }
        return str;
    }
}
  • 过滤器
  // 过滤Token
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String token = req.getHeader("token");
        // 检查白名单 白名单接口不需要判断是否有token
        if(chechWhiteList(req.getRequestURI())){
           filterChain.doFilter(servletRequest,servletResponse);
           return;
        }
        if(StringUtils.isEmpty(token)){

            // throw new CustomerException("401","身份认证失败");
            req.setAttribute("auth.error", new CustomException("401","身份认证失败"));
            req.getRequestDispatcher("/excepion/error").forward(servletRequest, servletResponse);
        }
        // 会员信息
        Object obj =  redisTemplate.opsForValue().get("token:"+token);
        if(obj == null ){
           // throw new CustomerException("401","身份认证失败");
            req.setAttribute("auth.error", new CustomException("401","用户登录已过期"));
            req.getRequestDispatcher("/excepion/error").forward(servletRequest, servletResponse);
        }
        UserInfoResp userInfo = (UserInfoResp) obj;
        userInfo.setSid(token);
        UserUtils.setLoginUser(userInfo);
        filterChain.doFilter(servletRequest, servletResponse);
    }

2、全局捕获异常原理

2.1 Filter过滤器发生在Controller之前。

拦截到控制层的异常,而Filter在Controller之前,Controller层的异常捕获,是无法捕获到还没有请求到Controller时发生的异常的。

2.2 全局捕获异常是对Controller中的异常处理。

3、实现对Filter中异常处理

方案一:将异常抛到controller层,交由全局捕获异常处理
如果要捕获Filter异常,只能通过控制器层定义的全局异常处理来捕获;那么也就只能想办法让Filter中的异常发送到Controller,再由Controller抛出异常,最后由全局异常捕获。

方案二:

参考:https://blog.csdn.net/flyer5/article/details/103836207

相关文章

网友评论

      本文标题:springboot 全局捕获异常无法捕获Filter中异常

      本文链接:https://www.haomeiwen.com/subject/fdzkektx.html