Синтаксис фильтра Grails, или Как вызвать фильтр Grails вне Grails - PullRequest
7 голосов
/ 10 августа 2009

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?

Ответы [ 2 ]

5 голосов
/ 11 августа 2009

В следующем коде 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()

В этом примере filters - это замыкание, которое вызывает метод с именем myFilter и передает карту и замыкание. Вы можете думать о myFilter как:

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

Карта может содержать ключи, такие как контроллер, действие или URI. Подстановочный знак (*) используется, когда Grails пытается сопоставить URI из HTTP-запроса, когда он пытается определить, какое замыкание вызвать.

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

0 голосов
/ 10 августа 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...