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

Spring Boot上传图片到static/pictures目录报NoSuchFileException如何解决

问题根本原因

Spring Boot项目的src/main/resources/static、/META-INF/resources等目录都会在项目打包时被嵌入到jar/war包内部,运行状态下没有可直接写入的文件系统路径,这是你写路径抛出java.nio.file.NoSuchFileException的核心原因。不要尝试写入jar包内部的resources目录,这个思路本身就不可行,必须存到jar包外部的独立目录,再配置Spring MVC映射这个目录的资源访问路径,就能让Thymeleaf正常读取。

步骤1:配置外部存储路径

你可以自定义一个jar包外的绝对路径作为上传目录,比如系统用户目录下的子目录,或者独立的data目录,推荐在配置文件中配置可灵活修改的参数:

# application.properties配置,Linux/macOS写法
upload.path=/data/app/upload/pictures/
# Windows写法
# upload.path=D:/app/upload/pictures/

在Controller中注入配置的路径,同时补充目录不存在时自动创建的逻辑,避免无目录抛出异常:

//working
@Value("${upload.path}")
private String uploadPath;

@PostMapping("/upload")
public String singleFileUpload(@RequestParam("file") MultipartFile file,
                               RedirectAttributes redirectAttributes) {
    try {
        // 新增目录判断逻辑,目录不存在时自动创建所有父目录
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        // Get the file and save it somewhere
        byte[] bytes = file.getBytes();
        Path path = Paths.get(uploadPath + file.getOriginalFilename());
        Files.write(path, bytes);

        redirectAttributes.addFlashAttribute("message",
                "You successfully uploaded '" + file.getOriginalFilename() + "'");

    } catch (IOException e) {
        e.printStackTrace();
    }

    return "index";
}
步骤2:配置Spring MVC资源映射

新增Web配置类,把本地上传目录映射为可通过URL访问的资源路径,这样Thymeleaf才能读取到上传的文件:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebResourceConfig implements WebMvcConfigurer {
    @Value("${upload.path}")
    private String uploadPath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 所有访问/pictures/路径下的请求,都会去uploadPath对应的本地目录找文件
        registry.addResourceHandler("/pictures/**")
                .addResourceLocations("file:" + uploadPath);
    }
}
步骤3:Thymeleaf引用上传文件写法

比如你上传了一张名为avatar.jpg的图片,在Thymeleaf模板中直接用映射后的路径访问即可:

<img th:src="@{/pictures/avatar.jpg}" alt="用户上传头像">

注意事项

  • 生产环境需要给配置的上传目录开通应用进程的读写权限
  • 建议对上传的文件名做重命名处理(比如加UUID前缀),避免同名文件覆盖
  • 不要使用相对路径配置upload.path,统一用绝对路径避免不同运行环境路径不一致的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:36:03