0

在我的一个控制器中,我在 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?

有没有更好的办法?

4

3 回答 3

0

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

如果我错过了更好的方法,我会留下这个问题。

于 2011-02-19T16:04:26.480 回答
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 更改为您的控制器/动作,这也在上面的链接中提到。

于 2011-02-20T16:25:00.150 回答
0

我知道这已经有几年了,但我认为这个问题仍然相关。

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

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

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

def someAction(MyCommandObject command) {}

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

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

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

于 2015-06-12T18:52:27.957 回答