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

Spring应用打包为Jar后静态资源路径异常问题排查

问题原因与解决方案

路径中"!"的含义

这个"!"是Java用来标识Jar包内部资源的分隔符,完整路径jar:file:/xxx.jar!/BOOT-INF/classes!/static/logo_joyjob.png表示:logo_joyjob.png是在joyjobcore-0.0.1-SNAPSHOT.jar压缩包内部的BOOT-INF/classes/static目录下,它不是文件系统中独立存在的真实文件,而是Jar包内的一个压缩条目。

为什么IntelliJ运行正常,Jar包运行报错?

IntelliJ启动应用时,直接从本地磁盘的build/classes目录加载资源——这些是真实存在的文件,所以ResourceUtils.getFile()能正常找到对应路径。但打包成Jar后,资源被压缩到Jar包内部,无法通过File对象访问,此时用ResourceUtils.getFile()就会抛出文件找不到的异常。

解决方法

修改CardUploader类中读取静态资源的代码,放弃ResourceUtils.getFile(),改用Spring的资源加载方式读取资源流:

方案1:注入ResourceLoader

import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.io.IOException;

@Component
public class CardUploader {
    private final ResourceLoader resourceLoader;

    public CardUploader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @PostConstruct
    public void onInit() {
        try (InputStream inputStream = resourceLoader.getResource("classpath:static/logo_joyjob.png").getInputStream()) {
            // 在这里处理图片资源流,比如读取内容、转换为字节数组等
        } catch (IOException e) {
            // 处理资源加载异常
            e.printStackTrace();
        }
    }
}

方案2:用@Value直接注入Resource

import org.springframework.core.io.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.io.IOException;

@Component
public class CardUploader {
    @Value("classpath:static/logo_joyjob.png")
    private Resource logoResource;

    @PostConstruct
    public void onInit() {
        try (InputStream inputStream = logoResource.getInputStream()) {
            // 处理图片资源流
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

关于build.gradle的配置

你的build.gradle配置没有问题,Spring Boot默认会把src/main/resources下的静态资源打包到Jar包的BOOT-INF/classes目录中,资源本身是存在的,问题完全出在代码读取资源的方式上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:24:58