Grails:在beforeInterceptor中渲染一个页面

时间:2011-02-19 16:02:24

标签: grails grails-controller

在我的一个控制器中,我在beforeInterceptor闭包中编写了一些错误检查代码。

 if (getUser()?.courses?.size() == 0) {
        render(view: '/base/errorMessage', model: [errorMessage: "You don't have any courses!"]);
        return false;
 }

该渲染调用显示一个漂亮的程序范围的错误页面。

但是,如果我返回false,则不会显示任何内容!如果我返回true,则错误页面显示正常,但操作仍然执行(它不会被渲染,但逻辑仍然被执行)。这需要重复的错误检查,从而破坏了拦截器的目的。

redirect()调用仍然可以正常工作,但将错误显示移动到另一个操作则很麻烦。用户将在其URL中看到/ app / error / errorMessage,而不是/ app / courses,并且可以直接进入错误页面。然后是将消息传递给该动作的问题 - flash.message? session.var?

有更好的方法吗?

3 个答案:

答案 0 :(得分:0)

更新:Filters显然不会遇到这个问题。但是,这需要将逻辑与控制器分开。不是世界末日。

我会留下这个问题,以防万一我错过了更好的方式。

答案 1 :(得分:0)

我建议您查看Grails URL Mapping, Section 6.4.4 (mapping by response code):您可以将请求重定向到"共享500服务器错误页面"

static mappings = {
   "500"(controller:"errors", action:"serverError")
   "404"(controller:"errors", action:"notFound")
   "403"(controller:"errors", action:"forbidden")
}

此外,我想您可能不知道您可以将URL更改为您的控制器/操作,这也在上面的链接中提到。

答案 2 :(得分:0)

我知道这已经有几年了,但我认为问题仍然存在。

Grails提供了一种更方便的方法来验证表单输入并使用命令对象和i18n message.properties返回flash错误消息。

基本上,你不需要编写拦截器。您可以在控制器中创建一个命令对象,其中包含您希望在提交时获得的所有表单域。然后为每个字段创建验证约束,并为约束违规错误创建i18n消息。

现在,当您定义控制器操作并将命令对象作为参数插入时:

def someAction(MyCommandObject command) {}

命令对象参数的作用有点像beforeInterceptor,因为Grails自动将表单提交中的数据绑定到命令对象的匹配属性 - 但是等等!那还不是全部! Grails还将约束应用于表单中的数据,并且基本上运行command.validate()所有 BEFORE 在操作中执行任何代码。这就是为什么在执行操作中的任何其他代码之前检查命令对象实例是否错误的常见做法,如下所示:

def someAction(MyCommandObject command) {
    if(command.hasErrors()){
        //do something -- set flash message error and redirect, etc.
    }
    //other importand code follows ...
}

我希望这可以帮助那些可能发现这个问题的人。这只是命令对象有用和强大的一个例子。