修改/覆盖Grails插件提供的过滤器

时间:2013-05-07 11:24:23

标签: grails filter

在我的Grails项目中,我想覆盖插件提供的过滤器,以便更好地满足我的需求。

更具体地说,定义了过滤器,使其应用​​于所有控制器上的所有操作:filterName(controller:"*", action:"*") { ... },我想将其限制为仅限于某些控制器。

我尝试在项目中创建一个与我想要覆盖的过滤器同名的过滤器类,但结果是每个请求都执行了两个过滤器。

那么有谁知道如何更改/覆盖/(甚至停用)插件提供的过滤器?提前致谢!

2 个答案:

答案 0 :(得分:2)

dmahapatro的回答让我找到了解决方案:关键概念是访问filterInterceptor bean,其中包含Grails应用程序中所有过滤器的定义。它可以被访问,例如在BootStrap.groovy文件中,以便在应用程序启动时修改可用的过滤器:

class BootStrap {
    def filterInterceptor

    def init = { servletContext ->
        // modify myPluginFilter provided by plugin so it 
        // is only applied to certain requests
        def myPluginFilterHandler = filterInterceptor.handlers.find{ it.filterConfig.name == 'myPluginFilter' }
        myPluginFilterHandler.filterConfig.scope.controller = 'myController'
        myPluginFilterHandler.filterConfig.scope.action = 'myAction'
        myPluginFilterHandler.afterPropertiesSet()

        log.info "myPluginFilter scope modified"
    }

    ...
}

此代码在应用程序启动时执行一次,它会找到过滤器myPluginFilter(例如,在插件中定义)并更改其范围(控制器和应用它的操作)。

通过从myPluginFilterHandler集合移除filterInterceptor.handlers,可以销毁过滤器而不是重新定义过滤器。

答案 1 :(得分:0)

您可以在项目的新过滤器类中尝试clearing handlers,例如:

blockPluginFilter(controller:"*", action:"*"){
    before = {
        def compInterceptor = applicationContext.getBean("filterInterceptor", CompositeInterceptor)
        compInterceptor.handlers?.clear()
    }
}

每个filter都有一个已注册为filterInterceptor的已配置的spring bean CompositeInterceptor,其中包含表示为filters的所有handlers句柄。如果您清除新过滤器中的handlers(如果没有延迟),则可以避免执行filter中的plugin。您可以在项目过滤器类中创建另一个过滤器来处理自定义逻辑。仅当插件的过滤器在此过滤器之后执行时,这才有效。您可以在插件的过滤器被点击之前清除任何其他位置的handlers