2009-08-10 91 views
7

Grails提供在控制器之前運行的filters。他們在像這樣的類定義:Grails過濾器語法或者如何在Grails外調用Grails過濾器

class SecurityFilters { 
    def filters = { 
     myFilter(controller:'*', action:'*') { // What are those weird colons?? 
      print "I'm filtering!" 
      // Code that does the filtering goes here 
     } 
    } 
} 

這些工作的偉大,但我想明白語法更好,因爲它看起來並不像任何Groovy代碼我以前見過。特別是,上面以myFilter開頭的行似乎很奇怪。這是一種稱爲myFilter的方法的方法定義嗎?如果是這樣,每個參數後:'*'是什麼意思?我認爲這可能是一個默認的參數值,但那將是='*'。我已經在方法調用之前看到使用冒號命名的參數,但是這不可能是方法調用,因爲我沒有在其他地方定義myFilter()

我想我會理解的要好得多,如果有人能告訴我如何從一個正常的Groovy類執行過濾代碼。換句話說,如果我有一個包含上面幾行的文件MyFilters.groovy,我該如何完成這個Groovy代碼,以便打印出「我正在過濾」?

import MyFilters 
def mf = new MyFilters() 
mf.filters.somethingGoesHere // Help! How do I finish this line so it calls my filtering code? 
+0

好問題松鼠!我剛剛一直在與同樣的問題作鬥爭 - 感謝您提出這個問題! – alpian 2010-09-24 16:50:49

+0

我需要知道相同的東西....我幾乎睡不着,哈哈! – Topera 2011-05-30 10:40:25

回答

5

下面Groovy代碼將打印「我過濾!」:

class SecurityFilters { 
    def filters = { 
     myFilter(controller:'*', action:'*') { // What are those weird colons?? 
      print "I'm filtering!" 
      // Code that does the filtering goes here 
     } 
    } 
} 

class FilterDelegate { 
    def methodMissing(String methodName, args) { 
     // methodName == myFilter 
     // args[0] == [controller:*, action:*] 
     // args[1] == {print "I'm filtering!"} 
     args[1].call() 
    } 
} 

def sf = new SecurityFilters() 
def filtersClosure = sf.filters 
filtersClosure.delegate = new FilterDelegate() 
filtersClosure.call() 

在這個例子中過濾器是調用一個方法命名爲myFilter並通過一張地圖和一個封閉的封閉。您可以將myFilter視爲:

myFilter([controller:'*', action:'*'], closure) 

該映射可以包含控制器,動作或uri等鍵。當Grails嘗試確定要調用哪個閉包時,它會嘗試與來自HTTP請求的URI相匹配時使用通配符(*)。

我對Grails如何處理過濾器的理解是使用委託加載器類。 loader類提供了一個methodMissing方法,併爲filters closure內的每個方法調用創建一個FilterConfig。當發出HTTP請求時,Grails將查看所有FilterConfig對象,並嘗試查找匹配的作用域(在地圖中查找控制器,動作或uri,並使用正則表達式在通配符上進行匹配)。如果它找到匹配項,它將調用傳遞給Filter類中的方法的閉包。

+0

很好的解釋 - 謝謝! – 2009-08-11 07:33:11

0

你不能方便地調用過濾器的Grails之外,因爲它們依賴於大量的管道,將建立不起來。行
myFilter(控制器:「」,動作:「」)
是這樣的方法定義,採用兩個參數,一個控制器和動作模式。 *表示將此過濾器應用於過程類型的任何對象。例如,如果我們想確保用戶不能創建任何東西,除非他們被授權,我們將使用以下過濾器。
controller:'*',action:'create'
這意味着任何時候創建操作被調用時,存儲在該函數體中的代碼都會執行,但是對於list,show或edit,將不會執行任何過濾器。如果你真的想要細節,你可以隨時下載grails源代碼。
編輯:
代碼編譯,因爲它是一個過濾器中定義的函數。

+0

謝謝 - 我知道過濾器及其控制器和操作模式在Grails中如何工作。但我想知道爲什麼上面顯示的MyFilter代碼是合法的Groovy。它編譯,但我不能解決爲什麼! – 2009-08-10 21:19:38