You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 03:57:42