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

+0

Мне НУЖНО знать что-то .... Я почти не могу спать, LOL! – Topera

ответ

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 пытается сопоставить URI с HTTP-запросом, когда пытается определить, какое замыкание нужно вызвать.

Мое понимание того, как Grails обрабатывает фильтры, заключается в том, что используется класс загрузчика делегата. Класс loader предоставляет метод methodMissing и создает FilterConfig для каждого вызова метода внутри закрытия фильтров. Когда HTTP-запрос выполняется, Grails просматривает все объекты FilterConfig и пытается найти подходящую область (выглядит на карте для контроллера, действия или uri и использует регулярные выражения для соответствия на подстановочные знаки). Если он находит совпадение, он вызывает закрытие, которое было передано методу в классе Filter.

+0

Отличное объяснение - спасибо! –

0

Вы не можете легко вызвать фильтры за пределами грааля, потому что они зависят от большого количества сантехники, которые не будут установлены. Строка
myFilter (контроллер: '', действие: '')
- это определение метода, которое принимает два аргумента, контроллер и шаблон действия. * означает применить этот фильтр к любому объекту существующего типа. Например, если мы хотим, чтобы пользователи не могли создавать что-либо, если они не были авторизованы, мы будем использовать следующий фильтр.
controller: '*', action: 'create'
Это означало бы, что в любое время, когда было создано действие create, будет выполняться код, хранящийся в этом теле функции, но для списка, show или редактирования никакого фильтра не будет выполняться. Если вам действительно нужны детали, вы всегда можете скачать исходный код Grails.
Редактировать:
Код компилируется, так как это функция, определенная в фильтре.

+0

Спасибо - я знаю, как фильтры и их контроллер и шаблоны действий работают внутри Grails. Но я хотел бы знать, почему приведенный выше код MyFilter является законным Groovy.Он компилируется, но я не могу понять, почему! –

Смежные вопросы