首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring MVC 文件上傳完整指南:單檔、多檔、MultipartFile 實戰與配置避坑

     編輯:Java 相關知識

Spring MVC 以 MultipartFile 封裝上傳文件,配合 CommonsMultipartResolver 即可輕鬆實現單/多文件上傳。本文從配置、表單、Controller、服務層封裝四個層面,提供可直接落地的完整範例。

一、核心配置:multipartResolver

<!-- spring-mvc.xml -->
<bean id="multipartResolver" 
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="defaultEncoding" value="UTF-8"/>
  <property name="maxUploadSize" value="5242880"/> <!-- 5MB -->
  <property name="maxInMemorySize" value="1048576"/> <!-- 1MB 超過寫臨時檔 -->
</bean>
  • defaultEncoding:表單編碼,預防中文檔名亂碼
  • maxUploadSize:總請求大小上限 (bytes)
  • maxInMemorySize:記憶體緩衝閾值,超過自動寫入臨時目錄

二、上傳表單關鍵點

<form action="fileUpload.html" method="post" enctype="multipart/form-data">
  <input type="file" name="file"/> <!-- 單檔 -->
  <input type="submit" value="上傳"/>
</form>

<form action="filesUpload.html" method="post" enctype="multipart/form-data">
  <input type="file" name="files"/>
  <input type="file" name="files"/>
  <input type="file" name="files"/> <!-- 多檔:同 name -->
  <input type="submit" value="批次上傳"/>
</form>
必須 加上 enctype="multipart/form-data",否則請求體不會被解析為多部分,MultipartFile 會是 null。

三、Controller 實作

@Controller
@RequestMapping("/file")
public class FileUploadController {

  @Autowired HttpServletRequest request;

  /** 單檔上傳 */
  @PostMapping("/upload")
  public String upload(@RequestParam("file") MultipartFile file) {
    saveFile(file);
    return "redirect:/file/list.html";
  }

  /** 多檔上傳:同 name 綁定陣列 */
  @PostMapping("/uploads")
  public String uploads(@RequestParam("files") MultipartFile[] files) {
    if (files != null) {
      for (MultipartFile f : files) saveFile(f);
    }
    return "redirect:/file/list.html";
  }

  /** 共用儲存邏輯 */
  private boolean saveFile(MultipartFile file) {
    if (file == null || file.isEmpty()) return false;
    try {
      String realPath = request.getServletContext().getRealPath("/") + "upload/";
      File dir = new File(realPath);
      if (!dir.exists()) dir.mkdirs();
      // 防止檔名衝突:可加 UUID 前綴
      String filename = file.getOriginalFilename();
      file.transferTo(new File(realPath + filename));
      return true;
    } catch (IOException e) {
      e.printStackTrace();
      return false;
    }
  }

  /** 列出已上傳檔案 */
  @GetMapping("/list")
  public ModelAndView list() {
    String realPath = request.getServletContext().getRealPath("/") + "upload/";
    File dir = new File(realPath);
    String[] names = dir.list();
    ModelAndView mav = new ModelAndView("list");
    mav.addObject("files", names == null ? new String[0] : names);
    return mav;
  }
}

四、MultipartFile 常用方法速查

方法說明
getOriginalFilename()客戶端原始檔名 (含路徑風險,建議只取檔名)
getContentType()MIME 類型
getSize()檔案大小 (bytes)
getInputStream()讀取檔案流
transferTo(File dest)高效寫入目的地 (底層用 FileChannel)
isEmpty()是否為空檔

五、常見坑與最佳實踐

  1. 檔名衝突:生產環境請用 UUID + 原始副檔名 或 雪花算法 ID 重命名。
  2. 路徑遍歷攻擊:getOriginalFilename() 可能包含 ../,務必用 FilenameUtils.getName() 只取檔名。
  3. 大檔案記憶體:調大 maxInMemorySize 或直接配置臨時目錄 uploadTempDir。
  4. Spring Boot 專案:只需在 application.yml 配置 spring.servlet.multipart,無需手動定義 Resolver Bean。
  5. 單元測試:使用 MockMultipartFile 模擬上傳,無需真實 Servlet 容器。

總結

Spring MVC 文件上傳核心在於 CommonsMultipartResolver + enctype="multipart/form-data" + MultipartFile 參數綁定。掌握單檔/多檔綁定差異、封裝共用儲存邏輯、注意檔名安全與大檔配置,即可構建健壯的上傳功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved