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

管理员添加分类上传图片至项目目录,控制器抛出未处理IOException异常

解决Spring Boot Controller上传图片时未处理IOException的问题

需求:实现管理员添加分类时,将上传的图片保存到项目目录中。
问题:编写Controller代码时抛出「未处理的IOException类型异常」,相关代码如下:

@PostMapping("/saveCategory")
public String saveCategory(@ModelAttribute Category category, @RequestParam("file") MultipartFile file,
        HttpSession session) {
    System.out.println(file.getOriginalFilename());
    String imageName = file != null ? file.getOriginalFilename() : "default.jpg";
    category.setImageName(imageName);

    Boolean existCategory = categoryService.existCategory(category.getName());
    if (existCategory) {
        session.setAttribute("errorMsg", "Category name already exist");
    } else {
        Category saveCategory = categoryService.saveCategory(category);
        if (!ObjectUtils.isEmpty(saveCategory)) {
            session.setAttribute("errorMsg", "Not saved ! internally server error");
        } else {

            // first of all get the path onto which u want to upload the file.

File saveFile = new ClassPathResource("static/img").getFile();

Path path = Paths.get(saveFile.getAbsolutePath() + File.separator + "category_img" + File.separator+ file.getOriginalFilename());

            // System.out.println(path);
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);

            session.setAttribute("succMsg", "Saved successfully");

        }
    }

    return "redirect:/admin/Category";
}

问题原因

  1. 未处理IO异常:代码中ClassPathResource.getFile()、Files.copy()等IO操作方法会抛出IOException,但当前方法既未声明抛出该异常,也未用try-catch捕获,导致编译报错。
  2. 路径获取方式有缺陷:ClassPathResource.getFile()仅在IDE运行时有效,项目打包成JAR包后,JAR内的资源并非真实文件系统路径,会引发运行时IO异常。
  3. 空文件判断不足:仅判断file != null,未检查文件是否为空,直接调用file.getOriginalFilename()可能触发空指针异常。

解决方案

1. 处理IO异常

在Controller方法签名上声明抛出IOException,或用try-catch块包裹IO操作代码,让异常得到合法处理。

2. 替换路径获取方式

使用ServletContext获取项目静态资源的真实路径,兼容IDE运行与JAR包运行场景。

3. 完善文件校验

增加文件是否为空的判断,避免空指针。

修改后的完整代码

@PostMapping("/saveCategory")
public String saveCategory(@ModelAttribute Category category, @RequestParam("file") MultipartFile file,
                           HttpSession session, ServletContext servletContext) throws IOException {
    // 完善文件空判断
    String imageName = file != null && !file.isEmpty() ? file.getOriginalFilename() : "default.jpg";
    category.setImageName(imageName);

    Boolean existCategory = categoryService.existCategory(category.getName());
    if (existCategory) {
        session.setAttribute("errorMsg", "分类名称已存在");
    } else {
        Category saveCategory = categoryService.saveCategory(category);
        if (!ObjectUtils.isEmpty(saveCategory)) {
            session.setAttribute("errorMsg", "保存失败!服务器内部错误");
        } else {
            // 通过ServletContext获取静态资源真实路径
            String uploadPath = servletContext.getRealPath("static/img/category_img");
            File uploadDir = new File(uploadPath);
            // 确保目标目录存在
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            // 拼接文件完整路径
            Path path = Paths.get(uploadPath + File.separator + file.getOriginalFilename());
            
            // 执行文件复制
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);

            session.setAttribute("succMsg", "保存成功");
        }
    }

    return "redirect:/admin/Category";
}

关键修改说明

  • 声明抛出IOException:方法签名后添加throws IOException,将异常交由Spring框架统一处理,也可自行用try-catch捕获并做自定义错误提示。
  • ServletContext获取路径:servletContext.getRealPath()能正确返回运行时静态资源目录的物理路径,解决JAR包运行时的路径问题。
  • 创建目标目录:通过uploadDir.mkdirs()自动创建多级目录,避免因目录不存在导致的文件写入失败。
  • 严格文件校验:file != null && !file.isEmpty()同时校验文件对象和文件内容,避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:33:14