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

Servlet 3.0 原生文件上傳實戰:零第三方依賴,注解驅動輕量級實現

     編輯:Java 綜合教學

Servlet 3.0 原生文件上傳:零依賴、注解驅動、極簡實現

一、環境要求

Servlet 3.0 規範內建文件上傳支持,需 Tomcat 7+ 容器。若在低版本 Tomcat 強行引入 servlet-api-3.0.jar 易發生類衝突,建議直接升級容器版本。

二、核心代碼實現

@WebServlet(name = "uploadServlet", urlPatterns = "/uploadServlet")
@MultipartConfig  // 關鍵:聲明該 Servlet 處理 multipart/form-data 請求
public class ServletUpload extends HttpServlet {
    private static final long serialVersionUID = 2527441790014487640L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        try {
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

            // 1. 獲取所有 Part(文件+普通字段)
            Collection<Part> parts = request.getParts();
            if (parts == null || parts.isEmpty()) {
                throw new ServletException("上傳內容為空");
            }

            // 2. 遍歷處理
            for (Part part : parts) {
                String header = part.getHeader("content-disposition");
                String fileName = getFileName(header); // 解析原始文件名
                // 3. 寫入磁盤(此處示例寫死 D盤,生產環境應配置化)
                part.write("d:/" + fileName);
            }
            response.getWriter().write("上傳成功");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("上傳失敗: " + e.getMessage());
        }
    }

    /** 從 content-disposition header 解析文件名,並生成 UUID 防重名 */
    private String getFileName(String header) {
        // header 形式: form-data; name="file"; filename="xxx.jpg"
        String suffix = header.substring(header.lastIndexOf("."), header.length() - 1);
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return uuid + suffix;
    }
}

三、@MultipartConfig 關鍵屬性詳解

屬性類型默認值說明
fileSizeThresholdint0當上傳文件大小超過此閾值(字節),內容從內存寫入臨時文件
locationString""臨時文件存儲目錄(不配置則用容器默認臨時目錄)
maxFileSizelong-1單個文件最大允許大小,-1 表示無限制
maxRequestSizelong-1整個 multipart 請求最大大小(含所有文件+表單字段),-1 無限制

四、前端表單關鍵點

<form action="uploadServlet" method="post" enctype="multipart/form-data">
    <input type="file" name="myFile" multiple="multiple" />
    <button type="submit">上傳</button>
</form>
  • method="post":GET 請求無請求體,無法上傳文件。
  • enctype="multipart/form-data":必須設置,否則請求體不會被解析為 Part。
  • name 屬性:每個上傳控件必須有 name,Servlet 才能識別。
  • multiple:HTML5 屬性,支持多文件同時選擇。

五、進階建議(生產環境必做)

  1. 文件名衝突處理:使用 UUID / 雪花算法 / 時間戳+隨機數 重命名,保留原始擴展名。
  2. 存儲路徑配置化:通過屬性文件或環境變量注入 location,區分開發/測試/生產環境。
  3. 文件類型/大小校驗:前端限制 + 後端二次校驗(MIME 類型、魔數檢測、大小限制)。
  4. 異步上傳與進度條:結合 Servlet 3.1 異步 Servlet + 前端 XMLHttpRequest/Fetch 實現大文件分片上傳、斷點續傳。
  5. 安全防護:防止惡意腳本上傳(禁用執行權限、單獨存儲域名、病毒掃描)。

六、總結

Servlet 3.0 原生上傳 API 通過 @MultipartConfig + request.getParts() 實現了「零第三方依賴、代碼極簡、容器原生支持」的輕量級文件上傳,適合中小項目、微服務組件、快速原型開發。大型系統建議封裝通用上傳組件,集成雲存儲(OSS/S3)、CDN 分發、圖片處理等能力。

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