【问题标题】:modify/override filter provided by Grails plugin修改/覆盖 Grails 插件提供的过滤器
【发布时间】:2013-05-01 07:58:52
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: grails filter


    【解决方案1】:

    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(例如,在插件中定义)并更改其范围(应用它的控制器和操作)。

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

    【讨论】:

    • 这个解决方案的缺点是如果重新加载过滤器定义(例如在开发模式下修改或添加过滤器时),修改后的过滤器将保留其原始定义,因为BootStrap.groovy中的代码仅在应用程序启动时执行一次。但是,这在生产模式下应该不是问题。
    • 我找到了一个解决方案,我有一个插件指定def loadAfter = ['filters'],然后在doWithApplicationContext 中修改handlers filterInterceptor bean 上的集合
    【解决方案2】:

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

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

    每个filter 都有一个已配置的spring bean filterInterceptor 注册为CompositeInterceptor,它具有所有filters 的句柄,表示为handlers。如果您清除新过滤器中的handlers(如果不是迟到的话),那么您可以避免从plugin 执行filter。您可以在项目过滤器类中创建另一个过滤器来处理您的自定义逻辑。这仅在插件的过滤器在此过滤器之后执行时才有效。你可以在任何其他地方清除handlers,但在插件的过滤器被点击之前。

    【讨论】:

    • 感谢您的回答;它让我深入了解了如何在运行时以编程方式修改过滤器定义。我通过在BootStrap.groovy 中仅访问一次filterInterceptor 修改了您的解决方案,然后更改了过滤器的定义。我将其作为单独的答案发布并接受了。
    猜你喜欢
    • 2011-03-16
    • 2014-09-07
    • 2018-02-19
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2013-03-20
    相关资源
    最近更新 更多