Spring Webflux项目JAR运行时JasperReport模板抛出FileNotFoundException求助
问题根因
- 你代码中硬编码的
src/main/resources/reports/是开发阶段的本地源码目录结构,项目打包为Spring Boot JAR后,src/main/resources下的所有资源会被编译到JAR包的BOOT-INF/classes/目录下,运行时不存在src/main/resources这个路径 ResourceUtils.getFile()只能读取文件系统中独立存在的文件,无法读取压缩在JAR包内部的classpath资源,所以打包运行时必然抛出文件找不到异常
修复方案
通过Spring的ResourceLoader加载classpath下的资源,直接用输入流提交给JasperReports进行编译,不需要依赖本地File对象:
@Slf4j @Service public class ReportService { // 路径修改为classpath下的reports目录 private static final String REPORTS_BASE_PATH = "classpath:reports/"; // 注入Spring的资源加载器 @Autowired private ResourceLoader resourceLoader; public ByteArrayInputStream exportReport( String reportFileName, Integer idCC, Map<String,Object> parameters ) throws Exception { Connection connection = CustomEntityManagerFactoryPostgresImpl .getInstance() .getConnection(idCC); // 读取JAR包内的资源流 Resource resource = resourceLoader.getResource(REPORTS_BASE_PATH + reportFileName); try (InputStream inputStream = resource.getInputStream()) { JasperReport jasperReport = JasperCompileManager.compileReport(inputStream); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream); return new ByteArrayInputStream(outputStream.toByteArray()); } } }
优化建议
- 生产环境建议提前将
.jrxml报表文件编译为.jasper二进制文件一起打包,运行时直接加载不需要编译,既提升性能也避免运行时编译的依赖冲突 - 确认项目构建配置(pom.xml/build.gradle)中没有排除
reports目录下的报表文件,保证资源正常被打包到JAR包内
内容的提问来源于stack exchange,提问作者xavier
相关产品推荐
相关产品推荐

