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

Spring MVC 文件上傳:Commons FileUpload 封裝實戰

     編輯:Java 相關知識

前言

Spring 內建對 Apache Commons FileUpload 的封裝,提供 CommonsMultipartResolver 開箱即用。本文通過動態多文件上傳案例,演示前端動態生成文件域、後端 Controller 處理、Spring 配置全流程。

前端頁面:動態增加文件輸入框

<form method="post" action="./upload.do" enctype="multipart/form-data">
    <div id="uploadDiv">
        <input type="file" name="file1" />
    </div>
    <input type="button" value="繼續上傳" onclick="addFileInput()">
    <input type="hidden" id="fileCount" name="fileCount" value="1">
    <input type="submit" value="上傳">
</form>

<script>
function addFileInput() {
    var count = Number(document.getElementById('fileCount').value) + 1;
    var div = document.createElement('div');
    div.id = 'divFile' + count;
    div.innerHTML = "<input type='file' name='file" + count + "'>";
    document.getElementById('uploadDiv').appendChild(div);
    document.getElementById('fileCount').value = count;
}
</script>

Command Bean

public class UploadForm {
    private byte[] file; // 單文件綁定,多文件由 Request 直接獲取
    public byte[] getFile() { return file; }
    public void setFile(byte[] file) { this.file = file; }
}

Controller 核心邏輯

public class FileUploadController extends SimpleFormController {
    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
                                    Object command, BindException errors) throws Exception {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        int fileCount = Integer.parseInt(request.getParameter("fileCount"));

        for (int i = 1; i <= fileCount; i++) {
            CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file" + i);
            if (file != null && !file.isEmpty()) {
                File dest = new File("E:/upload/" + file.getOriginalFilename());
                FileCopyUtils.copy(file.getBytes(), dest);
            }
        }
        return new ModelAndView("uploadSuccess");
    }

    /** 關鍵:註冊 ByteArrayMultipartFileEditor 支援 byte[] 綁定 */
    @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
            throws ServletException {
        binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
    }
}

Spring 配置

web.xml

<servlet>
    <servlet-name>springStudy</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springStudy</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

springStudy-servlet.xml

<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="50000000"/> <!-- 50MB -->
    <property name="defaultEncoding" value="utf-8"/>     <!-- 解決中文文件名亂碼 -->
</bean>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/upload.do">uploadController</prop>
        </props>
    </property>
</bean>

<bean id="uploadController" class="com.example.FileUploadController">
    <property name="commandClass" value="com.example.UploadForm"/>
    <property name="formView" value="uploadForm"/>
    <property name="successView" value="uploadSuccess"/>
</bean>

核心原理解析

  1. DispatcherServlet 攔截請求,檢測 multipart/form-data 內容類型。
  2. 委派 CommonsMultipartResolver 解析請求,將其包裝為 MultipartHttpServletRequest。
  3. CommonsMultipartResolver 繼承 CommonsFileUploadSupport,底層調用 Commons FileUpload API。
  4. Controller 通過 multipartRequest.getFile(name) 獲取 CommonsMultipartFile,提供 getBytes()、getInputStream()、transferTo(File) 等便捷方法。

常見問題與優化

  • 中文文件名亂碼:設置 defaultEncoding="utf-8",Tomcat 8+ 另需 URIEncoding="UTF-8"。
  • 大文件內存溢出:配置 maxInMemorySize 閾值,超過寫入臨時文件。
  • 進度條支援:需引入 Apache Commons FileUpload 1.3+ 的 ProgressListener 或使用 Servlet 3.0 @MultipartConfig + 異步上傳。
  • Spring Boot 時代:僅需 spring.servlet.multipart.enabled=true 即可自動配置,無需手動定義 Resolver。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved