Синтаксис фильтра Grails, или, Как назвать Фильтр Grails вне Grails

Видел интересный на днях, возможно, неделя, на блоге, который я не могу помнить. В основном я не могу приписать себе это, но я думал, что это могло бы иметь некоторое полезное приложение.

Говорят, что Вы хотели, чтобы абстрактный класс был замечен другим блоком, но Вы не хотите, чтобы кто-то был в состоянии наследоваться ему. Изолированный не будет работать, потому что это абстрактно по причине, другие классы в том блоке действительно наследовались ему. Частный не будет работать, потому что Вы могли бы хотеть объявить Родительский класс где-нибудь в другом блоке.

namespace Base.Assembly
{
  public abstract class Parent
  {
    internal abstract void SomeMethod();
  }

  //This works just fine since it's in the same assembly.
  public class ChildWithin : Parent
  {
    internal override void SomeMethod()
    {
    }
  }
}

namespace Another.Assembly
{
  //Kaboom, because you can't override an internal method
  public class ChildOutside : Parent
  {
  }

  public class Test 
  { 

    //Just fine
    private Parent _parent;

    public Test()
    {
      //Still fine
      _parent = new ChildWithin();
    }
  }
}

, Как Вы видите, это эффективно позволяет кому-то использовать Родительский класс не имея возможности для наследования.

7
задан Douglas Squirrel 10 August 2009 в 14:38
поделиться

2 ответа

Следующий код 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()

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

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

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

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

5
ответ дан 7 December 2019 в 12:23
поделиться

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

0
ответ дан 7 December 2019 в 12:23
поделиться