The Springboot project cannot capture the exception solution in the Filter

When using Spring Security to perform jwt verification with a filter, the global exception returns an exception that is not caught in the Filter. hereby record

Reason : Spring BootSince global exception handling @RestControllerAdvicewill only catch Controllerexceptions thrown by all layers, the exception class thrown in the filter is unaware.
Solution : transfer the exception to the Controller in the filter

Inject it in the filter HandlerExceptionResolver and resolver.resolveException()pass the exception to the Controller:

@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;

The complete Filter code is as follows:

@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
    
  @Resource
  private RedisUtil redisUtil;

  @Autowired
  @Qualifier("handlerExceptionResolver")
  private HandlerExceptionResolver resolver;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
    
    // 获取token
    String token = request.getHeader("token");
    // 如果请求头中不包含token直接放行
    if (StringUtils.isBlank(token)) {
    
    
      filterChain.doFilter(request, response);
      return;
    }
    // 解析token
    String userId = null;
    try {
    
    
      Claims claims = JwtUtil.parseJWT(token);
      userId = claims.getSubject();
    } catch (BaseException e) {
    
    
      log.error("非法的token:{}", token);
      //throw new BaseException(ResultCode.TOKEN_VALIDATE_LOSE);
      resolver.resolveException(request, response, null, new BaseException(ResultCode.TOKEN_VALIDATE_LOSE));
      return;
    }
    // 从redis中获取用户信息
    String redisKey = "login:" + userId;
    LoginUser loginUser = (LoginUser) redisUtil.get(redisKey);
    if (Objects.isNull(loginUser)) {
    
    
      //throw new BaseException(10007, "用户未登录");
      // 交给全局异常处理类处理
      resolver.resolveException(request, response, null, new BaseException(10007, "用户未登录"));
      return;
    }
    // 存入SecurityContextHolder
    // loginUser.getAuthorities()获取权限信息封装到Authentication
    UsernamePasswordAuthenticationToken authenticationToken =
        new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    // 放行
    filterChain.doFilter(request, response);
  }
}

Custom exception class:

@EqualsAndHashCode(callSuper = true)
@Data
public class BaseException extends RuntimeException {
    
    
  private static final long serialVersionUID = 7939259259170410861L;
  //错误代码
  private Integer code;

  // 错误信息
  private String message;

  public BaseException() {
    
    
    super();
  }

  public BaseException(ResultCode resultCode) {
    
    
    super(resultCode.getMessage());
    this.code = resultCode.getCode();
    this.message = resultCode.getMessage();
  }

  public BaseException(Integer code, String message) {
    
    
    super(message);
    this.code = code;
    this.message = message;
  }

  @Override
  public synchronized Throwable fillInStackTrace() {
    
    
    return this;
  }
}

Global catch exception class:


@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    
    
  @ExceptionHandler(value = BaseException.class)
  public ResponseResult<String> baseExceptionHandler(BaseException e) {
    
    
    String s = CommonUtils.exceptionInfo(e);
    log.error("发生业务异常!异常处在:[{}] , 原因是:[{}]", s, e.getMessage());
    return new ResponseResult<>(e.getCode(), e.getMessage());
  }

  @ExceptionHandler(value = NullPointerException.class)
  public ResponseResult<String> exceptionHandler(NullPointerException e) {
    
    
    String s = CommonUtils.exceptionInfo(e);
    log.error("发生空指针异常!异常处在:[{}] , 原因是:[{}]", s, e.getMessage());
    return new ResponseResult<>(ResultCode.BODY_NOT_MATCH);
  }

  @ExceptionHandler(value = Exception.class)
  public ResponseResult<String> exceptionHandler(Exception e) {
    
    
    String s = CommonUtils.exceptionInfo(e);
    log.error("未知异常!异常处在:[{}] , 原因是:[{}]", s, e.getMessage());
    return new ResponseResult<>(ResultCode.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());
  }

Guess you like

Origin blog.csdn.net/qq_60361946/article/details/128405169