You need to enable JavaScript to run this app. Grails 4.x.x环境下GrailsPageFilter导入失败问题及解决方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

Grails 4.x.x环境下GrailsPageFilter导入失败问题及解决方案咨询

Grails 4.x 适配GrailsPageFilter导入问题

问题背景

  • 原org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter类在Grails 2.x版本中可正常导入运行,切换到Grails 4.x.x环境后编译报错找不到该类,无法正常使用
  • 原有业务目标是自定义GSP标签,把动态生成的JS代码注入到页面<head>区域,避免JS直接渲染在页面内容块中
  • 项目当前Gradle依赖配置:
compile group: 'org.codehaus.groovy', name: 'groovy-dateutil', version: '2.5.0'

原有业务实现代码

def buttonDropDown = { attrs, body ->
    def id = attrs.id
    def r = grailsApplication.mainContext.getBean('org.grails.plugin.resource.ResourceTagLib')
    r.require(module: "jquery-ui")

    StringBuilder builder = new StringBuilder();
    builder.append('<button ')
            .append('id="' + id + '" >')
            .append(body).append('</button>')
    StringBuilder jsbuilder = new StringBuilder();
    jsbuilder.append(' <script type="text/javascript">')
            .append(' $(document).ready(function(){')
            .append(' $("#' + id + '").button({icons: {primary: "ui-icon-locked"},text: true);')
            .append(' });')
            .append('</script>')

    def headerWriter = getHeaderWriter()
    headerWriter << jsbuilder
    out << builder.toString()
}

private getHeaderWriter() {
    def gspSitemeshPage = request[GrailsPageFilter.GSP_SITEMESH_PAGE]
    def headBuffer = gspSitemeshPage.metaClass.getProperty(gspSitemeshPage, 'headBuffer')
    return headBuffer.writer
}

适配方案

  1. 更换类的导入路径
    Grails 4 全量完成了包名体系迁移,把原org.codehaus.groovy.grails前缀的包结构全部替换为org.grails命名空间,原GrailsPageFilter类的新导入路径为:

    import org.grails.web.sitemesh.GrailsPageFilter
    

    注意:这个类默认打包在Grails Web核心组件里,标准Grails 4 Web工程不需要额外加Gradle依赖,直接导入即可使用。

  2. 简化原反射逻辑
    原来通过Groovy metaClass反射取headBuffer的写法已经可以简化,Grails 4中Sitemesh的Page对象提供了公开API直接获取head缓冲区,改写后的getHeaderWriter方法如下:

    private getHeaderWriter() {
        // request中存储GSP_SITEMESH_PAGE的常量值没有变化,取值逻辑保持不变
        def gspSitemeshPage = request[GrailsPageFilter.GSP_SITEMESH_PAGE]
        // 直接调用公开API获取head缓冲区的Writer,去掉冗余的反射调用
        return gspSitemeshPage.head.writer
    }
    
  3. 其他兼容调整

    • 原代码中从Spring上下文获取ResourceTagLib的逻辑,对应Grails 2时代的Resources插件,Grails 4默认使用Asset-pipeline做静态资源管理,不需要手动获取该Bean,直接在标签逻辑中调用Asset-pipeline的内置方法引入jquery-ui模块即可
    • 原Gradle配置里的compile作用域已经在Grails 4中被废弃,建议替换为implementation;同时groovy-dateutil的版本会由Grails官方BOM统一托管,不需要手动写死版本号,避免出现版本冲突

内容的提问来源于stack exchange,提问作者Asif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 10:15:04