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

JavaBean實現多文件上傳兩大協議方案:HTTP Multipart與FTP對比實戰

     編輯:關於JSP

文件上傳是B/S系統標配。JSP本身不提供上傳API,需通過ServletRequest.getInputStream()解析原始數據流。本文對比HTTP Multipart(RFC 1867)與FTP協議兩種JavaBean實現方案的原理、代碼骨架與選型建議(環境:Win2000 + Apache + Tomcat 4.0 + JDK 1.4)。

方案一:HTTP Multipart 標準表單上傳

前端表單規範

<form method="POST" action="upload.jsp" enctype="multipart/form-data">
    <input type="file" name="file1" size="50"><br>
    <input type="file" name="file2" size="50"><br>
    <input type="submit" value="Upload">
</form>
  • enctype="multipart/form-data":瀏覽器按RFC 1867編碼,將文件二進制與表單字段混合在請求體中,以boundary分隔各Part。
  • 單表單可含多個<input type="file">實現多文件並發上傳。

JavaBean解析核心流程(testUpload類)

public class testUpload {
    public testUpload() { ... }
    public void initialize(ServletConfig config) throws ServletException { ... }
    public void upload() throws UploadException, IOException, ServletException { ... }
    private void getDataSection() { ... }  // 解析boundary、定位文件數據段
    private void getDataHeader() { ... }   // 解析Content-Disposition獲取文件名、字段名
    public int save(String destPath) throws UploadException, IOException, ServletException { ... }
}

關鍵步驟:

  1. request.getInputStream()獲取原始字節流。
  2. 讀取Content-Type頭提取boundary字符串。
  3. 按--boundary分割Part,解析每Part頭部(Content-Disposition: form-data; name="file1"; filename="a.txt")。
  4. 提取文件名、字段名,將Part體字節流寫入目標文件/數據庫BLOB。
  5. 處理結尾--boundary--標記。

HTTP方案優缺點

優點缺點
瀏覽器原生支持,無需客戶端插件大文件(>100MB)易超時、內存壓力大
防火牆/代理友好(走80/443端口)斷點續傳、並發分塊需前端JS配合複雜
Session天然集成,權限控制簡單單連接吞吐受限於HTTP協議開銷

方案二:FTP 協議上傳(FTPClient)

適用於:超大文件、內網高速傳輸、需斷點續傳、服務端存儲與Web服務器分離。

核心代碼骨架

import org.apache.commons.net.ftp.FTPClient;

public class FtpUploader {
    public boolean upload(String server, int port, String user, String pass,
                          String remoteDir, Map<String, InputStream> files) {
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(server, port);
            ftp.login(user, pass);
            ftp.enterLocalPassiveMode(); // 關鍵:被動模式穿透防火牆
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.changeWorkingDirectory(remoteDir);

            for (Map.Entry<String, InputStream> e : files.entrySet()) {
                ftp.storeFile(e.getKey(), e.getValue()); // 流式直傳
            }
            ftp.logout();
            return true;
        } catch (IOException ex) {
            ex.printStackTrace();
            return false;
        } finally {
            try { ftp.disconnect(); } catch (IOException ignored) {}
        }
    }
}

FTP方案優缺點

優點缺點
大文件傳輸穩定,支持斷點續傳(REST/APPE命令)需客戶端支持(Applet/ActiveX/HTML5 File API + 後端代理)
傳輸層面無HTTP頭開銷,帶寬利用率高防火牆/NAT穿透複雜(需被動模式+端口範圍開放)
存儲服務器可獨立擴展、異地備份用戶認證體系與Web分離,需同步賬號或Token授權

選型決策矩陣

場景推薦方案理由
常規業務附件(<50MB)、公網用戶HTTP Multipart零客戶端依賴、開發最快、權限集成簡單
大文件(>100MB)、內網高速上傳FTP / SFTP穩定性、續傳、帶寬效率優勢明顯
雲原生、對象存儲(OSS/S3)HTTP直傳OSS(預簽名URL)卸載Web服務器帶寬、無限擴展、CDN加速下載
需客戶端多文件拖拽、進度條、分片上傳HTTP + 前端分片庫 + 後端合並現代Web標準體驗,Plupload/Uppy/WebUploader成熟

現代化最佳實踐

  • HTTP上傳:採用Commons FileUpload或Servlet 3.0@MultipartConfig + request.getPart(),避免手寫解析器。
  • 安全:文件類型白名單(檢測Magic Number)、文件名隨機化、存儲路徑非Web訪問目錄、病毒掃描集成。
  • 大文件:前端分片(Blob.slice)、後端臨時目錄合並、Redis記錄分片狀態、支持秒傳(MD5秒傳)。
  • FTP/SFTP:使用Apache Commons Net或JSch,連接池化FTPClient,避免頻繁握手。

協議選型本質是業務場景與基礎設施的匹配。現代架構傾向「HTTP上傳到對象存儲」,FTP逐步退居內部數據交換場景。

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