Le projet Springboot ne peut pas capturer la solution d'exception dans le filtre

Lorsque vous utilisez Spring Security pour effectuer une vérification jwt avec un filtre, l'exception globale renvoie une exception qui n'est pas interceptée dans le filtre. enregistrer par la présente

Raison : Spring Bootétant donné que la gestion globale des exceptions @RestControllerAdvicen'intercepte que Controllerles exceptions lancées par toutes les couches, la classe d'exception lancée dans le filtre n'en est pas consciente.
Solution : transférer l'exception vers le Controller dans le filtre

Injectez-le dans le filtre HandlerExceptionResolver et resolver.resolveException()passez l'exception au Controller :

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

Le code complet du filtre est le suivant :

@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);
  }
}

Classe d'exception personnalisée :

@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;
  }
}

Classe d'exception de capture globale :


@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());
  }

Je suppose que tu aimes

Origine blog.csdn.net/qq_60361946/article/details/128405169
conseillé
Classement