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

Spring MVC 文件上傳與下載完整實戰:單文件、多文件、CommonsMultipartResolver 配置

     編輯:Java 綜合教學

Spring MVC 文件上傳下載實戰指南

Spring MVC 通過 CommonsMultipartResolver 封裝 Apache Commons FileUpload,提供優雅的文件上傳 API。本文涵蓋解析器配置、表單要求、單/多文件上傳 Controller 代碼、文件下載三要素、以及 App 端上傳說明。

1. 核心配置:CommonsMultipartResolver

在 Spring 配置文件中定義 id 必須為 multipartResolver:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="defaultEncoding" value="UTF-8"/>
  <property name="maxUploadSize" value="10485760"/> <!-- 10MB -->
  <property name="maxInMemorySize" value="1048576"/>  <!-- 1MB 以下內存暫存 -->
</bean>

依賴 JAR(放入 WEB-INF/lib 或 Maven):

  • commons-fileupload-1.3.3.jar
  • commons-io-2.6.jar

2. 前端表單關鍵點

<form method="post" action="/upload" enctype="multipart/form-data">
  <input type="file" name="file" />  <!-- name 必須與 Controller 參數一致 -->
  <input type="submit" value="上傳"/>
</form>
  • enctype="multipart/form-data" 必須設置。
  • name="file" 對應後端 MultipartFile file 或 CommonsMultipartFile file。

3. 單文件上傳 Controller(推薦 @RequestParam 方式)

@Controller
public class UploadController {

    @RequestMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) return "error";

        String originalName = file.getOriginalFilename();
        String suffix = originalName.substring(originalName.lastIndexOf("."));
        String newName = UUID.randomUUID().toString() + suffix;

        String rootPath = request.getServletContext().getRealPath("/upload");
        File destDir = new File(rootPath);
        if (!destDir.exists()) destDir.mkdirs();

        File destFile = new File(destDir, newName);
        try {
            file.transferTo(destFile); // Spring 內部使用 FileCopyUtils
        } catch (IOException e) {
            e.printStackTrace();
            return "error";
        }
        return "success";
    }
}

注意:@RequestParam("file") 必須加,否則綁定失敗報錯。

4. 多文件上傳

@RequestMapping("/multiUpload")
public String multiUpload(@RequestParam("files") MultipartFile[] files, HttpServletRequest request) {
    for (MultipartFile file : files) {
        if (!file.isEmpty()) {
            // 同單文件處理邏輯
            String newName = UUID.randomUUID() + file.getOriginalFilename().substring(...);
            file.transferTo(new File(uploadDir, newName));
        }
    }
    return "success";
}

前端:<input type="file" name="files" multiple/>

5. 文件下載三要素

@RequestMapping("/download")
public void download(HttpServletResponse response, @RequestParam String fileName) throws IOException {
    String realPath = request.getServletContext().getRealPath("/upload/" + fileName);
    File file = new File(realPath);
    if (!file.exists()) { response.sendError(404); return; }

    // 1. 設置編碼
    response.setContentType("application/octet-stream;charset=UTF-8");
    // 2. Content-Disposition: attachment; filename=編碼後文件名
    String encodedName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
    response.setHeader("Content-Disposition", "attachment;filename=" + encodedName);
    // 3. Content-Length
    response.setHeader("Content-Length", String.valueOf(file.length()));

    // 字節流輸出
    try (InputStream in = new FileInputStream(file);
         OutputStream out = response.getOutputStream()) {
        byte[] buffer = new byte[1024 * 1024];
        int len;
        while ((len = in.read(buffer)) > 0) out.write(buffer, 0, len);
    }
}

6. App 端上傳說明

Android/iOS 同樣使用 HTTP multipart/form-data 格式,只需在請求頭設置 Content-Type: multipart/form-data; boundary=xxx,後端 Controller 代碼完全復用,無需區分 Web/App。

7. 進階建議

  • 大文件分片上傳:前端分片(如 plupload)、後端合併(臨時目錄 + 完成信號合併)。
  • 上傳進度條:需引入 ProgressListener 或前端 XMLHttpRequest upload 事件。
  • 安全:校驗文件類型(Magic Number)、限制大小、存儲路徑與 Web 根目錄隔離、文件名隨機化防覆蓋/遍歷。
  • 雲存儲對接:上傳至 OSS/S3 後保存 URL,本地不存文件實體。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved