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

Spring MVC 文件上傳實戰:Multipart 解析器配置、虛擬目錄存儲與 Controller 實現

     編輯:Java 綜合教學

整體架構:Spring MVC 如何處理 multipart/form-data

瀏覽器上傳文件時,表單需設置 enctype="multipart/form-data",請求體將包含多個部分,每部分對應一個表單字段或文件。Spring MVC 通過 MultipartResolver 介面統一解析,核心實現 CommonsMultipartResolver 依賴 Apache Commons FileUpload。

步驟一:添加依賴

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<!-- 間接依賴 commons-io:2.2 -->

步驟二:配置 MultipartResolver

在 Spring MVC 配置文件(如 springmvc.xml)中聲明 Bean:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5242880" /> <!-- 5MB -->
    <property name="maxInMemorySize" value="1048576" /> <!-- 1MB 閾值,超過寫臨時文件 -->
    <property name="defaultEncoding" value="UTF-8" />
</bean>

關鍵屬性:maxUploadSize 限制總大小;maxInMemorySize 控制內存緩衝閾值,防止大文件撐爆堆內存。

步驟三:配置圖片訪問虛擬目錄(生產環境建議)

上傳文件不應放在 Webapp 目錄下(重新部署會丟失、靜態資源服務壓力大)。推薦方案:

  • Nginx 反向代理靜態目錄:將磁盤目錄(如 /data/upload/images)映射為 /images/**。
  • Tomcat 虛擬目錄:server.xml 中 <Context docBase="/data/upload/images" path="/images" />。
  • 按日期分級存儲:/images/2024/05/20/uuid.jpg,避免單目錄文件過多導致 I/O 性能下降。

步驟四:JSP 頁面與 Controller 實現

JSP 表單片段

<form action="${pageContext.request.contextPath}/items/editItemsSubmit" method="post" enctype="multipart/form-data">
    <c:if test="${items.pic != null}">
        <img src="/images/${items.pic}" width="100" height="100" />
    </c:if>
    <input type="file" name="items_pic" />
    <input type="submit" value="提交" />
</form>

Controller 方法

@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(
        Model model, HttpServletRequest request,
        Integer id,
        @ModelAttribute("items") @Validated(ValidGroup1.class) ItemsCustom itemsCustom,
        BindingResult bindingResult,
        MultipartFile items_pic) throws Exception {

    // 1. 校驗文件
    String originalFilename = items_pic.getOriginalFilename();
    if (items_pic != null && originalFilename != null && originalFilename.length() > 0) {
        // 2. 生成唯一文件名:UUID + 原始後綴
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = UUID.randomUUID().toString() + suffix;

        // 3. 寫入磁盤(生產環境應注入存儲服務抽象層)
        String picPath = "D:/tmp/"; // 應從配置讀取
        File newFile = new File(picPath + newFileName);
        items_pic.transferTo(newFile); // Commons FileUpload 核心方法

        // 4. 保存文件名至領域對象
        itemsCustom.setPic(newFileName);
    }

    // 5. 業務邏輯:更新數據庫...
    itemsService.updateItems(itemsCustom);
    return "success";
}

進階優化點

  • 流式上傳:大文件(>100MB)建議使用 StandardServletMultipartResolver(Servlet 3.0+ 原生支持)或分片上傳插件。
  • 文件類型校驗:結合 Content-Type、魔數檢測防止偽裝腳本上傳。
  • 雲存儲對接:將 transferTo 替換為 OSS SDK 上傳,Controller 無感遷移。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved