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

Spring MVC文件上傳完整指南:Commons FileUpload 與 Servlet 3.0 兩種實現

     編輯:Java 相關知識

Spring MVC 提供統一的 MultipartFile 抽象,底層可插拔 CommonsMultipartResolver (Apache Commons FileUpload) 或 StandardServletMultipartResolver (Servlet 3.0+ 內置)。本文對比兩種方案,並演示 HTML5 多文件上傳與進度條實現。

一、通用前端表單

<form:form action="product_save" method="post" commandName="product" enctype="multipart/form-data">
    <form:input path="name"/>
    <form:input path="description"/>
    <form:input path="price"/>
    <input type="file" name="images[0]"/> <!-- HTML5 多文件可用 name="images" multiple -->
    <input type="submit"/>
</form:form>

二、領域對象

public class Product implements Serializable {
    private Long id;
    private String name, description, price;
    private List<MultipartFile> images; // 接收上傳文件列表
    // Getter/Setter
}

三、方案一:Commons FileUpload (傳統通用)

1. 依賴

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

2. Spring 配置

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="2000000"/> <!-- 2MB -->
</bean>
<mvc:resources mapping="/image/**" location="/image/"/> <!-- 靜態資源映射 -->

3. 控制器

@PostMapping("/product_save")
public String save(HttpServletRequest req, @ModelAttribute Product product, BindingResult br, Model model) {
    List<MultipartFile> files = product.getImages();
    if (files != null) {
        for (MultipartFile f : files) {
            if (!f.isEmpty()) {
                String fileName = f.getOriginalFilename();
                File dest = new File(req.getServletContext().getRealPath("/image"), fileName);
                f.transferTo(dest);
            }
        }
    }
    model.addAttribute("product", product);
    return "ProductDetails";
}

四、方案二:Servlet 3.0+ 內置支持 (無額外 JAR)

1. web.xml 配置 multipart-config

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <multipart-config>
        <max-file-size>20848820</max-file-size>        <!-- 20MB -->
        <max-request-size>418018841</max-request-size>     <!-- 400MB -->
        <file-size-threshold>1048576</file-size-threshold> <!-- 1MB 超過寫磁盤 -->
        <location>/image/</location>                       <!-- 臨時文件目錄 -->
    </multipart-config>
</servlet>

2. Spring 配置解析器

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>

3. 控制器代碼完全不變

五、進階:HTML5 多文件上傳 + 進度條 (純前端 AJAX)

1. 領域對象簡化

public class UploadFile { private MultipartFile multipartFile; /* getter/setter */ }

2. 控制器

@PostMapping("/file_upload")
@ResponseBody
public void upload(HttpServletRequest req, @ModelAttribute UploadFile uf, BindingResult br) {
    MultipartFile f = uf.getMultipartFile();
    File dest = new File(req.getServletContext().getRealPath("/image"), f.getOriginalFilename());
    f.transferTo(dest);
}

3. 前端頁面 (關鍵:XMLHttpRequest 上傳進度事件)

<input type="file" id="files" multiple>
<button id="upLoadButton">Upload</button>
<div id="bar">0%</div>
<script>
var totalSize = 0, uploaded = 0, fileCount = 0, uploadedCount = 0;
$('#files').on('change', function(e) {
    var files = e.target.files;
    fileCount = files.length;
    for (var i=0; i= fileCount) return;
    var file = $('#files')[0].files[uploadedCount];
    var fd = new FormData();
    fd.append('multipartFile', file);
    var xhr = new XMLHttpRequest();
    xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
            var pct = Math.round((e.loaded + uploaded) * 100 / totalSize);
            $('#bar').css('width', pct + '%').text(pct + '%');
        }
    };
    xhr.onload = function() {
        uploaded += file.size;
        uploadedCount++;
        uploadNext();
    };
    xhr.open('POST', 'file_upload');
    xhr.send(fd);
}
</script>

六、方案對比總結

維度Commons FileUploadServlet 3.0+ 內置
額外依賴commons-fileupload、commons-io無
容器要求Servlet 2.4+Servlet 3.0+ (Tomcat 7+, Jetty 9+)
配置位置Spring XML Beanweb.xml + Spring Bean
臨時文件控制Resolver 屬性web.xml multipart-config
性能成熟穩定原生實現,略優

七、最佳實踐建議

  1. 新項目優先 **Servlet 3.0+ 方案**,減少依賴、配置更集中
  2. 生產環境必須設置 maxUploadSize/max-file-size 防止惡意大文件撐爆磁盤
  3. 文件存儲建議雲存儲 (S3/OSS) 或獨立文件服務器,避免應用節點有狀態
  4. 上傳類型白名單驗證:f.getContentType() + 文件頭魔數檢查
  5. 進度條方案適用於中小文件;大文件建議分片上傳 + 斷點續傳 (Plupload/WebUploader/自定義)

掌握兩種解析器切換與 HTML5 進度上傳,可應對從傳統表單到現代富交互的各類文件上傳場景。

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