2009-08-10 58 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