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
相关产品推荐
相关产品推荐

