Grails 3部署war包到Tomcat后无法创建文件流、读取i18n资源失败问题
问题原因分析
- 开发环境正常的原因:Grails开发模式以项目源码根目录作为工作目录运行,
new File("grails-app/i18n/${params.id}")使用的相对路径可以直接定位到源码目录下的对应文件,因此第一个判断分支可以正常执行。 - WAR包部署后失败的原因:
- 部署到Tomcat后,Java进程的工作目录是Tomcat自身的启动目录,不是WAR包解压后的应用目录,因此直接用File类读取
grails-app/xxx相对路径必然找不到文件,会进入else分支。 - Grails3打包为WAR时,
grails-app/i18n下的properties文件属于类路径资源,会被编译打包到WEB-INF/classes/i18n/目录下,不会保留在WEB-INF/grails-app/i18n/路径下,因此你通过ServletContext读取该路径的逻辑也会失效,最终进入最后的else分支返回找不到文件。
- 部署到Tomcat后,Java进程的工作目录是Tomcat自身的启动目录,不是WAR包解压后的应用目录,因此直接用File类读取
修复方案
直接使用类路径读取资源,不需要判断环境,开发和生产环境都可以兼容,示例代码如下:
def index= { log.debug params.id // 直接从类路径读取i18n资源 InputStream stream = Thread.currentThread().contextClassLoader.getResourceAsStream("i18n/${params.id}") if (stream) { log.debug "Streaming" render stream.text } else { log.debug "Not found" render '#Message bundle not found' } }
你也可以使用Grails提供的grailsApplication来读取类路径资源,写法如下:
def resource = grailsApplication.getResource("classpath:i18n/${params.id}") if (resource.exists()) { stream = resource.inputStream }
内容的提问来源于stack exchange,提问作者Rishav Jain
相关产品推荐
相关产品推荐

