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

Spring Boot中Maven未复制资源文件及读取异常问题求助

Spring Boot读取resources目录JSON文件遇到NoSuchFileException的问题解决

问题回顾

你在Spring Boot项目中尝试读取src/main/resources下的JSON文件,使用了这段代码:

File file = new File(this.getClass().getClassLoader().getResource(inputFileName).getFile());

但通过Spring Tools以「Run As -> Spring Boot App」运行时,抛出了NoSuchFileException,发现target/classes目录里并没有你的JSON文件。同时你的Maven classpath配置里包含了src/main/resources的条目,但文件就是没被复制过去。

为什么Maven没复制文件到target/classes?

看你提供的classpath配置里这一行:

<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">

问题出在excluding="**"这个属性上!它表示排除src/main/resources目录下的所有文件和子目录,Maven自然不会把任何资源文件复制到target/classes里。

正常情况下,src/main/resources是Maven默认的资源目录,不需要额外添加排除规则,这个配置应该是误加的。

解决步骤

第一步:修复Maven classpath配置

把src/main/resources条目里的excluding="**"去掉,修改后的配置如下:

<classpathentry kind="src" output="target/classes" path="src/main/resources">
  <attributes>
    <attribute name="maven.pomderived" value="true"/>
  </attributes>
</classpathentry>

然后执行mvn clean compile命令,Maven就会把src/main/resources下的文件复制到target/classes目录了。

第二步:改用Spring Boot推荐的资源读取方式(重要)

即使修复了classpath问题,你原来用new File()的方式也有隐患——当项目打包成jar包后,jar内部的资源并不是文件系统中的真实文件,这时候getFile()会返回一个奇怪的路径,依然会抛出异常。

推荐用以下几种方式读取资源:

方式1:注入ResourceLoader读取

这是最灵活的方式,适合动态指定文件名的场景:

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import java.io.InputStream;

@Component
public class JsonResourceReader {

    private final ResourceLoader resourceLoader;

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

    public void readJson(String fileName) throws Exception {
        // 用classpath:前缀指定资源位置
        Resource resource = resourceLoader.getResource("classpath:" + fileName);
        try (InputStream inputStream = resource.getInputStream()) {
            // 这里可以用Jackson/Gson等框架解析JSON
            // 示例:ObjectMapper mapper = new ObjectMapper();
            // YourDto dto = mapper.readValue(inputStream, YourDto.class);
        }
    }
}

方式2:用@Value直接注入资源

如果文件名是固定的,这种方式更简洁:

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

@Component
public class FixedJsonReader {

    // 直接注入指定的资源
    @Value("classpath:your-target-file.json")
    private Resource jsonResource;

    public void loadJson() throws Exception {
        try (InputStream inputStream = jsonResource.getInputStream()) {
            // 处理JSON流
        }
    }
}

方式3:传统的流读取方式(无Spring依赖时用)

如果不想依赖Spring的API,也可以用类加载器的流读取方式:

try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(inputFileName)) {
    if (inputStream == null) {
        throw new FileNotFoundException("无法找到资源文件: " + inputFileName);
    }
    // 处理输入流
}

总结

  1. 先修复classpath的排除规则,让Maven正确复制资源文件;
  2. 优先使用Spring提供的Resource相关API读取资源,适配本地开发和jar包运行两种场景;
  3. 避免用File对象读取classpath资源,因为jar环境下不支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:50:28