迁移至Java 17与Spring Boot 2.5.7后,部署到Tomcat时无法读取Resources目录下JSON文件的问题
迁移至Java 17与Spring Boot 2.5.7后,部署到Tomcat时无法读取Resources目录下JSON文件的问题
我之前也碰到过几乎一模一样的情况,问题其实出在你读取资源的方式上。当应用打包成WAR部署到Tomcat后,资源文件是嵌入在WAR包内部的,这时候ClassPathResource.getURI()返回的是类似jar:file:/path/to/your/war/WEB-INF/classes/db.mongo.query/FORM16.json格式的URI,而Paths.get()和Files.readAllBytes()是用来访问文件系统上的物理文件的,根本没法直接读取JAR/WAR包内的嵌套资源——这就是为什么本地运行没问题(本地资源是实打实的文件系统文件),一部署到Tomcat就报错的核心原因。
给你几个经过验证的解决方案:
方案一:用Spring Resource接口直接读流(最推荐)
Spring的ClassPathResource本身就提供了获取输入流的方法,完全不需要转成URI再用Files类读取,这种方式适配所有部署场景:
ClassPathResource resource = new ClassPathResource("db.mongo.query/" + this.name + ".json"); try (InputStream inputStream = resource.getInputStream()) { // 建议指定UTF-8编码,避免中文乱码 String query = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); // 后续处理逻辑 } catch (IOException e) { // 异常捕获与处理 }
方案二:检查打包配置是否正确
有时候版本迁移后,Maven/Gradle的默认资源打包规则可能有变化,你需要确认src/main/resources下的JSON文件是否被正确打包到WAR的WEB-INF/classes目录里。如果是Maven项目,可以在pom.xml里添加明确的资源配置:
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.json</include> <include>**/*.*</include> </includes> </resource> </resources> </build>
方案三:用类加载器读取资源流
如果你习惯用原生Java的方式,也可以通过类加载器的getResourceAsStream方法读取,原理和方案一一致:
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("db.mongo.query/" + this.name + ".json")) { if (inputStream == null) { throw new FileNotFoundException("未找到目标资源文件: db.mongo.query/" + this.name + ".json"); } String query = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); } catch (IOException e) { // 异常处理逻辑 }
另外你已经确认了Tomcat用户的读取权限,那基本可以排除权限问题,重点就放在资源访问方式的兼容性上,试试上面的方案应该就能解决问题了。
备注:内容来源于stack exchange,提问作者Komala Dunna
相关产品推荐
相关产品推荐

