异常未在调用方法中传播:能否在abc()中捕获控制器方法异常?
问题解答
核心结论
默认情况下,你无法在abc()方法的catch块中捕获oneMethod()或twoMethod()抛出的异常。
原因分析
你代码里的forward属于请求转发(类似Servlet的RequestDispatcher.forward),这种操作会将请求的处理权完全移交到目标控制器方法,原abc()方法的执行流程在此刻已经结束。当目标方法抛出异常时,异常会被Web容器的异常处理机制接管,不会回溯到原方法的try/catch块中。
无需修改目标方法的解决方案
如果不想改动oneMethod()或twoMethod()的代码,可以通过以下方式捕获并处理这些异常:
1. 配置全局异常处理器
在Web框架(从代码风格看你使用的是Grails)中配置全局异常处理器,统一捕获所有控制器抛出的异常。以Grails为例,可在grails-app/conf/spring/resources.groovy中注册处理器:
beans = { exceptionHandler(org.springframework.web.servlet.handler.SimpleMappingExceptionResolver) { exceptionMappings = [ 'java.lang.ArithmeticException': '/error/handleArithmetic' ] defaultErrorView = '/error/default' } }
之后编写对应的错误处理控制器,在其中完成日志记录或异常处理逻辑。
2. 用AOP切面拦截异常
通过面向切面编程(AOP)在目标方法执行的切面中捕获异常,无需修改目标方法代码。以Spring AOP为例,定义切面类:
@Aspect @Component class ExceptionLoggingAspect { private static final log = org.slf4j.LoggerFactory.getLogger(ExceptionLoggingAspect) @AfterThrowing( pointcut = "execution(* com.yourpackage.oneController.oneMethod(..)) || execution(* com.yourpackage.twoController.twoMethod(..))", throwing = "ex" ) void logException(Exception ex) { log.error("Error while downloading ICSR Report", ex) } }
该切面会在目标方法抛出异常后自动执行日志记录逻辑。
3. 框架专属过滤器/拦截器
如果是Grails框架,还可以使用Filters拦截请求,结合全局异常处理逻辑捕获异常:
class ExceptionFilters { def filters = { exceptionCapture(controller: 'oneController,twoController', action: '*') { afterView = { Exception ex -> if (ex) { log.error("Error while downloading ICSR Report", ex) } } } } }
内容的提问来源于stack exchange,提问作者Prickriti
相关产品推荐
相关产品推荐

