2011-02-19 33 views
0

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

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

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

但是,如果我返回false,则不会显示任何内容!如果我返回true,那么错误页面就会显示出来,但是该操作仍然执行(它不会被渲染,但逻辑仍然会被执行)。这需要重复的错误检查,否则拦截拦截器的目的。

重定向()调用仍然正常工作,但将错误显示移动到不同的操作是凌乱的。用户可以在他们的URL中看到/ app/error/errorMessage,而不是/ app/courses,并且可以直接进入错误页面。接下来就是将消息传递给该操作的问题 - flash.message? session.var?

有没有更好的方法?

回答

0

我知道这是几岁,但我认为这个问题仍然相关。

Grails通过使用Command Objects和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 ... 
} 

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

0

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

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

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") 
} 

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

+0

这并没有真正帮助我 - 我只是想拦截一个控制器并向用户显示一条消息。这不是一个实际的例外。 –