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

一、背景

系统定义了全局统一异常处理,使用了@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 中的回答

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值