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

Spring Boot应用运行时上传图片无法显示问题求助

问题描述

开发了一款支持图片上传的植物养护Web应用,遇到以下问题:

  • 应用运行期间上传的图片无法在页面显示,路径和引用均正确
  • 预先存放在src/main/resources/static/images文件夹中的图片可正常展示

HTML模板

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Plantenverzorging</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="all" th:href="@{mystyle.css}" href="mystyle.css"/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-custom">
    <div class="container-fluid">
        <a class="navbar-brand" href="#">Home</a>
    </div>
</nav>

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div>
                <h1>Plantenverzorging</h1>
                <p>Welkom bij Plantenverzorging, de webapplicatie die je helpt om je planten gezond en gelukkig te
                    houden.</p>
            </div>
        </div>
    </div>
    <div class="row">
        <div th:each="plant : ${plants}" class="col-md-4">
            <a th:href="@{|/plantdetails/${plant.id}|}">
                <img th:if="${plant.image != null}" th:src="@{${'/images/' + plant.image}}" src="../static/images/default-plant-image.jpg" class="img-responsive" th:alt="${plant.name}">
                <img th:unless="${plant.image != null}" th:src="@{/images/default-plant-image.jpg}" class="img-responsive" th:alt="${plant.name}">
            </a>
            <h2 th:text="${plant.name}"></h2>
            <p th:text="${plant.description}"></p>
        </div>
    </div>

    <div class="button-container">
        <a href="/add" class="btn btn-success btn-lg">Add</a>
        <a class="btn btn-danger btn-lg" style="margin-left: 10px;">Delete</a>
    </div>
</div>

</body>
</html>

AddController 代码

package be.thomasmore.eindopdracht.controllers;

import be.thomasmore.eindopdracht.models.Plant;
import be.thomasmore.eindopdracht.repositories.PlantRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Controller
public class AddController {
    @Autowired
    private PlantRepository plantRepository;

    @GetMapping("/add")
    public String addPlant(Model model) {
        model.addAttribute("plant", new Plant());
        return "add";
    }

    @PostMapping("/add")
    public String savePlant(@ModelAttribute("plant") Plant plant,
                            @RequestParam("file") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            String fileName = file.getOriginalFilename();
            String uploadDir = "C:/Users/felix/Documents/Programmeren/Advanced Programming Techniques/eindOpdracht/eindOpdracht/src/main/resources/static/images/";
            String filePath = uploadDir + fileName;
            File dest = new File(filePath);
            file.transferTo(dest);
            plant.setImage(fileName);
        }

        plantRepository.save(plant);

        return "redirect:/";
    }
}

Plant 实体类代码

package be.thomasmore.eindopdracht.models;

import jakarta.persistence.*;
import org.hibernate.annotations.GenericGenerator;

import java.util.UUID;

@Entity
public class Plant {
    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(columnDefinition = "BINARY(16)")
    private UUID id;
    private String name;
    private String description;
    private String deadlines;
    private String image;

    public Plant() {
    }

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDeadlines() {
        return deadlines;
    }

    public void setDeadlines(String deadlines) {
        this.deadlines = deadlines;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }
}

问题原因及解决办法

原因

Spring Boot运行时,src/main/resources目录下的文件会被打包到jar包中,应用启动后无法动态加载该目录下新增的文件。你将上传图片放到src/main/resources/static/images,运行时新增的文件不会被Spring的静态资源处理器识别,因此无法访问。

解决步骤

  1. 修改上传目录到项目外部
    把上传路径改为项目根目录外的独立文件夹,比如:

    String uploadDir = "C:/plant-uploads/images/";
    

    同时添加目录创建逻辑,确保目录存在:

    File dir = new File(uploadDir);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    
  2. 配置静态资源映射
    添加Spring Boot配置类,将外部上传目录映射为静态资源路径:

    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 WebConfig implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/images/**")
                    .addResourceLocations("file:C:/plant-uploads/images/");
        }
    }
    

    这样访问/images/xxx.jpg时,Spring会自动去外部目录查找对应文件。

  3. 优化文件名避免冲突
    可以给上传的图片重命名,比如用UUID拼接原文件名,防止覆盖已有文件:

    String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
    

内容的提问来源于stack exchange,提问作者Juanita Pardo Isidoro Rasgado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:27:35