添加Around拦截器后Exception Handler未触发,如何排除指定方法?
问题解决思路
你的问题根源在于日志拦截器捕获异常后没有重新抛出,导致Spring的全局异常处理器(@ExceptionHandler)无法感知到异常,自然不会触发handleException方法,最终返回null而非预期的ResponseEntity。下面提供两种可行解决方案:
方案一:排除handleException方法被拦截
修改拦截器的切点表达式,跳过handleException方法的拦截,同时保证异常能正常传递到全局异常处理器:
修改后的拦截器代码
@Around("execution(* com.coviddata..*(..)) && !execution(* com.coviddata..*.handleException(..))") public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable { Object temp = null; String inputString = getInput(joinPoint); logger.debug(inputString); try{ temp = joinPoint.proceed(); } catch (Exception e) { // 记录异常时传入异常对象,方便查看堆栈信息 logger.error(ERROR + " " + ((MethodSignature)joinPoint.getSignature()).getDeclaringTypeName() + " " + joinPoint.getSignature().getName(), e); // 重新抛出异常,让全局异常处理器捕获 throw e; } finally { logger.debug(OUT + ((MethodSignature)joinPoint.getSignature()).getReturnType()); } return temp; }
说明:
- 切点表达式中的
!execution(* com.coviddata..*.handleException(..))用于排除所有包下的handleException方法,若知道该方法的具体类路径,可写得更精确(比如!execution(* com.coviddata.controller.GlobalExceptionHandler.handleException(..))) - 必须重新抛出异常,否则异常会被拦截器吞掉,全局异常处理器依然无法触发
方案二:修复拦截器逻辑,让异常正常传播
无需排除handleException,只需在拦截器捕获异常后重新抛出,Spring会自动调用你的handleException方法返回正确的ResponseEntity:
修改后的拦截器代码
@Around("execution(* com.coviddata..*(..))") public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable { Object temp = null; String inputString = getInput(joinPoint); logger.debug(inputString); try{ temp = joinPoint.proceed(); } catch (Exception e) { // 记录异常日志,包含堆栈信息 logger.error(ERROR + " " + ((MethodSignature)joinPoint.getSignature()).getDeclaringTypeName() + " " + joinPoint.getSignature().getName(), e); // 关键:重新抛出异常,交给全局异常处理器处理 throw e; } finally { logger.debug(OUT + ((MethodSignature)joinPoint.getSignature()).getReturnType()); } return temp; }
说明:
- 该方案更简洁,无需调整切点,只需保证异常不被拦截器吞掉,Spring的异常处理机制就能正常工作
- 日志中传入异常对象
e很关键,能帮你快速定位异常发生的具体位置
内容的提问来源于stack exchange,提问作者khalid tounoussi
相关产品推荐
相关产品推荐

