全局统一异常处理无法拦截filter中catch的异常

7 篇文章 0 订阅

一、背景

系统定义了全局统一异常处理,使用了@RestControllerAdvice注解的方式。

@Slf4j
@RestControllerAdvice
@SuppressWarnings("unchecked")
public class GlobalExceptionHandlerAdvice {

    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public BaseResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException:" + e.getMessage());
        FieldError fe = (FieldError) e.getBindingResult().getAllErrors().get(0);
        String message = String.format("%s %s", fe.getField(), StringUtils.isNotBlank(fe.getDefaultMessage()) ? fe.getDefaultMessage() : e.getMessage());
        return BaseResponse.with(Code.PARAM_ERROR.getCode(), message);
    }
 @ExceptionHandler(JwtException.class)
    public BaseResponse handleJwtException(JwtException e) {
        log.error(e.getMessage(), e);
        return BaseResponse.with(Code.UN_AUTHORIZATION);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleException(Exception e) {
        log.error(e.getMessage(), e);
        return new ResponseEntity(BaseResponse.with(Code.SYSTEM_ERROR.getCode(), Code.SYSTEM_ERROR.getMsg()
                + " " + e.getClass().getName() + ":" + e.getMessage(), null), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

鉴权使用的是JWT,使用filter对token进行解析和验证。然后突然发现一个问题,就是当token过期时,抛出的异常无法通过全局统一异常处理对外返回,而是返回500。

 

二、原因

全局统一异常处理只能处理控制器中发生的异常。要在Spring Security过滤器链中重用此功能,需要定义过滤器并将其挂钩到安全配置中。过滤器需要将异常重定向到统一异常处理中。

 

三、代码

在filter中注入HandlerExceptionResolver

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

然后在catch中抛出

catch (Exception e) {
            e.printStackTrace();
            resolver.resolveException(request, response, null, e);
        }

之后在GlobalExceptionHandlerAdvice中定义需要处理的异常类型,本文中用的是JwtException

@ExceptionHandler(JwtException.class)
    public BaseResponse handleJwtException(JwtException e) {
        log.error(e.getMessage(), e);
        return BaseResponse.with(Code.UN_AUTHORIZATION);
    }

这时便可以跟在业务代码里面抛出的业务异常一样处理了。

 

四、备注

参考了https://stackoverflow.com/questions/34595605/how-to-manage-exceptions-thrown-in-filters-in-spring 中的回答

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
您好!对于 shiro 异常无法全局拦截的问题,可能有多种原因导致。下面是一些常见的处理方法,供您参考: 1. 确保正确配置了 Shiro 的异常处理器: 您可以在 Shiro 的配置文件指定一个全局异常处理器,用于捕获并处理所有异常。例如: ``` [main] ... [filters] ... [urls] ... [exception] unauthorizedUrl = /unauthorized unauthorizedHandler = com.example.UnauthorizedExceptionHandler ``` 2. 自定义异常处理器: 您可以创建一个自定义的异常处理器类来处理 Shiro 异常,并在 Shiro 配置文件指定使用该处理器。例如: ``` public class CustomExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 处理异常逻辑 ... return new ModelAndView("error"); } } ``` 3. 使用 AOP 拦截异常: 您可以使用 AOP 技术,在方法执行时拦截异常,并进行统一处理。例如,在 Spring 使用 @Aspect 注解来定义切面: ``` @Aspect @Component public class ExceptionAspect { @Around("execution(* com.example.*.*(..))") public Object handleException(ProceedingJoinPoint joinPoint) throws Throwable { try { // 执行目标方法 return joinPoint.proceed(); } catch (Exception e) { // 处理异常逻辑 ... return null; } } } ``` 需要根据您的具体情况进行调整和配置。希望以上方法能对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值