You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot以jar包部署时如何读取static目录下的静态资源文件

问题根源

  • 首次出现FileNotFoundException的原因:src/main/resources是开发阶段的源码目录,Maven/Gradle构建打包时,该目录下的文件会被编译拷贝到Spring Boot可执行Jar的BOOT-INF/classes/路径下,Jar包内部不存在src目录结构,用FileInputStream直接读取磁盘路径必然找不到文件。
  • 后续加载.jasper失败的原因:Jar包是压缩归档文件,内部的资源不能直接通过操作系统的文件路径访问,你大概率还是沿用了文件流的方式读取静态资源目录下的文件,没有使用类路径资源加载的方式读取。

正确实现方案

1. 调整资源存放路径

把提前编译好的.jasper文件放在src/main/resources/reports目录即可,无需放在static目录(static一般用于存放可对外暴露的前端访问资源,后端内部使用的资源单独建目录管理更清晰)。

2. 使用类路径方式加载资源

Spring Boot项目推荐直接注入ResourceLoader加载类路径资源,示例代码如下:

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

// 构造注入ResourceLoader
private final ResourceLoader resourceLoader;
public ReportService(ResourceLoader resourceLoader) {
    this.resourceLoader = resourceLoader;
}

public void exportPdf() {
    // 读取类路径下的.jasper文件
    Resource resource = resourceLoader.getResource("classpath:reports/Invoice.jasper");
    try (InputStream inputStream = resource.getInputStream()) {
        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(inputStream);
        // 后续填充数据、导出PDF逻辑
    } catch (Exception e) {
        // 异常处理逻辑
        e.printStackTrace();
    }
}

如果不想依赖Spring的ResourceLoader,也可以直接用JDK类加载器读取:

InputStream inputStream = getClass().getClassLoader().getResourceAsStream("reports/Invoice.jasper");

注意路径不要加前缀/,直接从类路径根目录写相对路径即可。

额外注意项

  • 提前编译.jrxml是更合适的生产环境方案,可避免运行时编译的性能开销和依赖缺失问题。
  • 确认你的构建工具(Maven/Gradle)没有排除.jasper后缀的文件,默认配置下resources目录下所有文件都会被打进Jar,如果自行修改过资源过滤规则,需要确认包含.jasper格式文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:12:00