Grails 2.2.3(基于JDK7)异常处理:能否用@ControllerAdvice替代try catch?
Grails 2.2.3 全局异常处理替代方案
Grails 2.2.3 不支持 Spring 3.2+ 引入的 @ControllerAdvice 注解,以下是几种适配该版本的全局异常处理可行方案:
1. 利用Grails内置UrlMappings全局异常映射
这是Grails原生支持的全局异常处理方式,无需修改现有控制器代码,直接通过路由配置统一转发异常请求。
在 grails-app/conf/UrlMappings.groovy 中添加异常映射:
class UrlMappings { static mappings = { // 针对特定异常的处理路由 "500"(controller: 'error', action: 'handleNullPointer') { exception = NullPointerException } // 全局捕获所有未处理异常 "500"(controller: 'error', action: 'handleGlobal') // 原有URL映射 "/$controller/$action?/$id?"{ constraints { // 约束配置 } } } }
创建对应的 ErrorController 处理异常逻辑:
class ErrorController { def handleNullPointer() { render view: '/errors/nullPointer', model: [message: '空指针异常,请检查数据或参数'] } def handleGlobal() { def exception = request.getAttribute('javax.servlet.error.exception') log.error("全局未处理异常:", exception) render view: '/errors/global', model: [errorMsg: exception?.message ?: '未知错误'] } }
2. 自定义拦截器捕获异常
通过Grails拦截器的 handleException 方法,在全局层面捕获控制器未处理的异常,统一处理响应。
创建拦截器文件 grails-app/conf/GlobalExceptionInterceptor.groovy:
class GlobalExceptionInterceptor { int order = HIGHEST_PRECEDENCE // 确保拦截器优先执行 boolean before() { true } boolean after() { true } void afterView() {} @Override boolean handleException(Exception e, String actionName, Object[] args) { log.error("全局捕获异常:", e) // 根据异常类型返回对应响应 if (e instanceof IllegalArgumentException) { response.status = 400 render(contentType: 'application/json') { [code: 400, msg: '参数非法:' + e.message] } } else { response.status = 500 render(contentType: 'application/json') { [code: 500, msg: '服务器内部错误'] } } return true // 标记异常已处理,终止传播 } }
在 grails-app/conf/Config.groovy 中注册拦截器:
grails.plugins.interceptors.includes = ['globalException']
3. 统一父控制器封装异常处理
创建基础父控制器,将异常处理逻辑封装为通用方法,所有业务控制器继承该父类,通过包裹代码块替代重复的try-catch。
基础父控制器 BaseController.groovy:
class BaseController { protected <T> T withErrorHandling(Closure<T> closure) { try { return closure.call() } catch (IllegalArgumentException e) { response.status = 400 render(contentType: 'application/json') { [code: 400, msg: '参数错误:' + e.message] } } catch (Exception e) { log.error("业务处理异常:", e) response.status = 500 render(contentType: 'application/json') { [code: 500, msg: '服务器异常'] } } return null } }
业务控制器继承并使用该方法:
class UserController extends BaseController { def getUser() { withErrorHandling { def userId = params.id as Long if (!userId) { throw new IllegalArgumentException("用户ID不能为空") } def user = User.get(userId) render(contentType: 'application/json') { user } } } }
内容的提问来源于stack exchange,提问作者Alireza Mousavi
相关产品推荐
相关产品推荐

