2011-02-19 29 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

這並沒有真正幫助我 - 我只是想攔截一個控制器並向用戶顯示一條消息。這不是一個實際的例外。 –