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 }
适配方案
更换类的导入路径
Grails 4 全量完成了包名体系迁移,把原org.codehaus.groovy.grails前缀的包结构全部替换为org.grails命名空间,原GrailsPageFilter类的新导入路径为:import org.grails.web.sitemesh.GrailsPageFilter注意:这个类默认打包在Grails Web核心组件里,标准Grails 4 Web工程不需要额外加Gradle依赖,直接导入即可使用。
简化原反射逻辑
原来通过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 }其他兼容调整
- 原代码中从Spring上下文获取
ResourceTagLib的逻辑,对应Grails 2时代的Resources插件,Grails 4默认使用Asset-pipeline做静态资源管理,不需要手动获取该Bean,直接在标签逻辑中调用Asset-pipeline的内置方法引入jquery-ui模块即可 - 原Gradle配置里的
compile作用域已经在Grails 4中被废弃,建议替换为implementation;同时groovy-dateutil的版本会由Grails官方BOM统一托管,不需要手动写死版本号,避免出现版本冲突
- 原代码中从Spring上下文获取
内容的提问来源于stack exchange,提问作者Asif
相关产品推荐
相关产品推荐

