如何替换已定义的 Servlet 过滤器(用 doWithSpring 替换遗留的 doWithWebDescriptor)

How to replace Servlet Filters already defined (replacing legacy doWithWebDescriptor with doWithSpring)

我正在尝试将 Grails 插件从版本 2.3.4 升级到 4.0.11。它使用不再支持的语法来用自己的过滤器替换名称为 sitemeshurlMapping 的过滤器。

下面的代码使用 xml 的 DSL。它替换了最终生成的 web.xml.

中的 xml 个节点
def doWithWebDescriptor = { xml ->
    def pageFilter = xml.filter.find { it.'filter-name'.text() == 'sitemesh' }
    def urlMappingFilter = xml.filter.find { it.'filter-name'.text() == 'urlMapping' }

    def grailsVersion = GrailsUtil.grailsVersion

    // Grails 1.3.x & Grails 2.0.x
    def pageFilterClass = "org.zkoss.zk.grails.web.ZKGrailsPageFilter"
    def urlMappingFilterClass = "org.zkoss.zk.grails.web.ZULUrlMappingsFilter"

    if(grailsVersion.startsWith("2")) {
        pageFilter.'filter-class'.replaceNode {
            'filter-class'(pageFilterClass)
        }
        urlMappingFilter.'filter-class'.replaceNode {
            'filter-class'(urlMappingFilterClass)
        }

        //
        // Require a legacy config for servlet version
        //
        if(application.metadata.getServletVersion() >= '3.0') {
            pageFilter.'filter-class' + {
                'async-supported'('true')
            }
            urlMappingFilter.'filter-class' + {
                'async-supported'('true')
            }
        }
    } else {
        pageFilter.'filter-class'.replaceBody(pageFilterClass)
        urlMappingFilter.'filter-class'.replaceBody(urlMappingFilterClass)
    }
}

到目前为止我尝试了什么

下面的代码使用 Grails 插件配置向 spring 的 FilterRegistrationBean 注册过滤器。我正在关注 Grails official documentation.

Closure doWithSpring() { { ->
    boolean supportsAsync = this.grailsApplication.metadata.getServletVersion() >= "3.0"

    pageFilter(FilterRegistrationBean) {
        name = "sitemesh"
        filter = bean(org.zkoss.zk.grails.web.ZKGrailsPageFilter)
        urlPatterns = ["/*"]
        order = Ordered.HIGHEST_PRECEDENCE
        asyncSupported = supportsAsync
    }

    urlMappingFilter(FilterRegistrationBean) {
        name = "urlMapping"
        filter = bean(org.zkoss.zk.grails.web.ZULUrlMappingsFilter)
        urlPatterns = ["/*"]
        order = Ordered.HIGHEST_PRECEDENCE
        asyncSupported = supportsAsync
    }
}}

如何使用 RegistrationBeans 复制遗留代码?

另外,我不知道 Grails 是否弃用了这些过滤器中的任何一个。如果可能的话,我想知道是否还有其他替代品。

Here's the project 以防有人需要更多上下文。

调试旧版本的插件我想到了以下内容:

pageFilter(FilterRegistrationBean) {
    name = "sitemesh"
    filter = bean(ZKGrailsPageFilter)
    urlPatterns = ["/*"]
    order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 50
    asyncSupported = supportsAsync
    dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR)
}

urlMappingFilter(FilterRegistrationBean) {
    name = "urlMapping"
    filter = bean(ZULUrlMappingsFilter)
    urlPatterns = ["/*"]
    order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 60
    asyncSupported = supportsAsync
    dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD)
}

添加了 dispatcherTypes 并更改了顺序,假设这些将是最后一个过滤器,其中 'pageFilter' 应该放在过滤器链中的 'urlMappingFilter' 之前。