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

AWS EC2实例中Spring Boot图片上传后无法显示问题求助

Spring Boot图片上传部署AWS EC2后无法显示的解决方案

本地开发Spring Boot图片上传、保存及展示功能正常,但部署到AWS EC2实例(WAR打包模式)后,数据库已正确保存图片文件名,但页面表格中无法显示图片。经排查,问题出在getRealPath()方法在WAR模式下无法将文件写入应用内部目录,需将图片保存到外部独立路径并配置静态资源映射,具体实现方案如下:

1. 配置外部存储路径

在application.properties中添加自定义的图片存储路径配置,便于后续维护:

# EC2上的图片存储绝对路径(需提前创建)
image.upload.dir=/opt/spring-boot-images/
# 前端访问图片的URL前缀
image.access.path=/images/**

注意:在EC2实例上执行以下命令创建目录并设置权限,确保Tomcat进程能读写:

sudo mkdir -p /opt/spring-boot-images/
sudo chown tomcat:tomcat /opt/spring-boot-images/
sudo chmod 755 /opt/spring-boot-images/

2. 修改控制器上传逻辑

移除request.getServletContext().getRealPath()的使用,改用配置的外部路径存储图片,同时生成唯一文件名避免覆盖:

@Controller
public class TeamMembersController {
    
    @Autowired
    TeamMembersRepository teamRepo;
    
    @Value("${image.upload.dir}")
    private String uploadDir;
    
    @RequestMapping("/teammembers")
    public String memberlist(Model model) {
        model.addAttribute("Members", teamRepo.findAll());
        model.addAttribute("command", new TeamMembers());
        return "teammembersback";
    }
    
    @RequestMapping(value ="/savamember", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String savemember(@RequestParam("MemberId") int id, 
                             @RequestParam("MemberName") String name, 
                             @RequestParam("Position") String position, 
                             @RequestParam("password") String password, 
                             @RequestParam("Bio") String bio, 
                             @RequestParam("Pic") MultipartFile pic) throws IOException {
        TeamMembers member = new TeamMembers();
        member.setMemberId(id);
        member.setMemberName(name);
        member.setPosition(position);
        member.setPassword(password);
        member.setBio(bio);
        
        // 生成唯一文件名,防止同名文件覆盖
        String originalFilename = pic.getOriginalFilename();
        String uniqueFilename = System.currentTimeMillis() + "_" + originalFilename;
        member.setPicture(uniqueFilename);
        
        teamRepo.save(member);
        
        // 创建存储目录(若不存在)
        File dir = new File(uploadDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        
        // 将文件保存到外部路径
        File destFile = new File(uploadDir + uniqueFilename);
        pic.transferTo(destFile);
        
        return "forward:/teammembers";
    }
    
    @RequestMapping(value="/deletemember/{id}",method = RequestMethod.GET)
    public String deletemember(@PathVariable int id){
        // 删除成员时同步删除对应图片
        TeamMembers member = teamRepo.findById(id).orElse(null);
        if (member != null) {
            File picFile = new File(uploadDir + member.getPicture());
            if (picFile.exists()) {
                picFile.delete();
            }
            teamRepo.deleteById(id);
        }
        return "forward:/teammembers";
    }
}

3. 配置静态资源映射

创建WebMvc配置类,将外部存储路径映射为可访问的静态资源URL:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Value("${image.upload.dir}")
    private String uploadDir;
    
    @Value("${image.access.path}")
    private String accessPath;
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 外部路径映射到指定URL前缀
        registry.addResourceHandler(accessPath)
                .addResourceLocations("file:" + uploadDir);
    }
}

4. 修改JSP页面图片访问路径

更新图片src属性,使用映射后的URL前缀访问图片:

<td><img width="100" src="/images/${member.picture}"></td>

部署验证

  1. 重新打包WAR文件并部署到EC2的Tomcat
  2. 上传新图片,检查EC2的/opt/spring-boot-images/目录是否生成对应文件
  3. 访问页面确认图片正常显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:55:02