管理员添加分类上传图片至项目目录,控制器抛出未处理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"; }
问题原因
- 未处理IO异常:代码中
ClassPathResource.getFile()、Files.copy()等IO操作方法会抛出IOException,但当前方法既未声明抛出该异常,也未用try-catch捕获,导致编译报错。 - 路径获取方式有缺陷:
ClassPathResource.getFile()仅在IDE运行时有效,项目打包成JAR包后,JAR内的资源并非真实文件系统路径,会引发运行时IO异常。 - 空文件判断不足:仅判断
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
相关产品推荐
相关产品推荐

