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

Java Servlet 整合 SmartUpload 實現文件上傳完整教學

     編輯:Java 相關知識

技術背景

SmartUpload 是早期商業級文件上傳組件,功能豐富 (支援進度條、大檔案分片、圖片縮圖等),但已停止維護、官網關閉、無 Maven 中央倉庫。現代專案強烈建議改用 Apache Commons FileUpload 或 Spring MultipartFile。本文僅供維護舊系統參考。

核心依賴

  • jspsmartupload.jar (需手動下載、安裝至本地倉庫或放入 WEB-INF/lib)

前端表單 (register.jsp)

<%@ page language="java" pageEncoding="GBK"%>
<!DOCTYPE html>
<html>
<head>
    <title>用戶註冊</title>
    <meta charset="GBK">
</head>
<body>
    <form action="RegisterServlet" method="post" enctype="multipart/form-data">
        暱稱: <input type="text" name="uname1" /><br/>
        用戶名: <input type="text" name="uname2" /><br/>
        密碼: <input type="password" name="password1" /><br/>
        確認密碼: <input type="password" name="password2" /><br/>
        性別: <input type="radio" name="sex" value="男" checked/>男
              <input type="radio" name="sex" value="女"/>女<br/>
        Email: <input type="text" name="email" /><br/>
        頭像: <input type="file" name="file1" /><br/>
        <input type="submit" value="完成註冊" />
    </form>
</body>
</html>

核心 Servlet 實作 (RegisterServlet.java)

package com.example.servlet;

import com.jspsmart.upload.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.io.*;

public class RegisterServlet extends HttpServlet {
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        request.setCharacterEncoding("GBK");
        response.setContentType("text/html;charset=GBK");
        
        SmartUpload smart = new SmartUpload();
        
        try {
            // 1. 初始化:SmartUpload 需要 PageContext (JSP 內建,Servlet 需手動建立)
            JspFactory jspFactory = JspFactory.getDefaultFactory();
            PageContext pageContext = jspFactory.getPageContext(
                this, request, response, "", true, 8192, true);
            smart.initialize(pageContext);
            
            // 2. 解析上傳請求
            smart.upload();
            
            // 3. 處理上傳檔案
            String savedPath = "";
            Files files = smart.getFiles();
            if (files.getCount() > 0) {
                File file = files.getFile(0); // 取第一個檔案
                if (!file.isMissing()) {
                    // 取得副檔名
                    String ext = file.getFileExt();
                    // 生成唯一檔名:IP + 時間戳 + 隨機數
                    String fileName = new IpTimeStamp(
                        request.getRemoteAddr()).getIpTimeRand() + "." + ext;
                    
                    // 儲存至伺服器 (相對路徑 headupload/)
                    file.saveAs("/headupload/" + fileName);
                    savedPath = "headupload/" + fileName;
                }
            }
            
            // 4. 取得一般表單欄位 (上傳後 request.getParameter 失效,需用 smart.getRequest())
            Request req = smart.getRequest();
            String uname1 = req.getParameter("uname1");
            String uname2 = req.getParameter("uname2");
            String password1 = req.getParameter("password1");
            String sex = req.getParameter("sex");
            String email = req.getParameter("email");
            
            // 5. 業務邏輯:存入資料庫 (略)
            // User user = new User(uname2, password1, uname1, sex, email, savedPath);
            // userDao.insert(user);
            
            // 6. 回應結果
            PrintWriter out = response.getWriter();
            out.println("註冊成功!頭像路徑: " + savedPath);
            
        } catch (SmartUploadException e) {
            e.printStackTrace();
            response.getWriter().println("上傳失敗: " + e.getMessage());
        }
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        doPost(req, resp);
    }
}

檔案命名工具類 (IpTimeStamp.java)

package com.example.util;

import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

public class IpTimeStamp {
    private String ip;
    private SimpleDateFormat sdf;

    public IpTimeStamp(String ip) { this.ip = ip; }

    /** 生成唯一標識:IP各段補零3位 + 時間戳(yyyyMMddHHmmssSSS) + 3位隨機數 */
    public String getIpTimeRand() {
        StringBuilder sb = new StringBuilder();
        if (ip != null) {
            String[] parts = ip.split("\\.");
            for (String part : parts) {
                sb.append(String.format("%03d", Integer.parseInt(part))); // 補零到3位
            }
            sb.append(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
            sb.append(new Random().nextInt(1000)); // 3位隨機數
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(new IpTimeStamp("192.168.3.222").getIpTimeRand());
        // 輸出範例: 19216800322220240115143025123456
    }
}

SmartUpload 關鍵 API 對照表

Commons FileUploadSmartUpload說明
DiskFileItemFactorySmartUpload (內建)工廠/解析器合一
ServletFileUpload.parseRequest()smart.upload()解析請求
FileItem.isFormField()無 (自動分離)SmartUpload 內部分離
FileItem.getString()smart.getRequest().getParameter()取得表單欄位
FileItem.getName()file.getFileName()取得檔名
FileItem.write(File)file.saveAs(path)儲存檔案
FileItem.getInputStream()file.getInputStream()取得輸入流
FileItem.getSize()file.getSize()檔案大小

SmartUpload 進階功能 (目前主流組件亦支援)

1. 檔案大小限制

smart.setMaxFileSize(1024 * 1024 * 5); // 5MB 單檔
smart.setTotalMaxFileSize(1024 * 1024 * 20); // 20MB 總計

2. 允許/禁止檔案類型

smart.setAllowedFilesList("jpg,jpeg,png,gif,pdf"); // 白名單
smart.setDeniedFilesList("exe,bat,sh,jsp,php,asp"); // 黑名單

3. 自動建立目錄

file.saveAs("/upload/" + fileName); // 會自動建立 upload 目錄

4. 記憶體/磁碟閾值

smart.setSizeThreshold(1024 * 1024); // 1MB 以上寫磁碟暫存

遷移指南:SmartUpload → Commons FileUpload

對應關係

// SmartUpload
SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.upload();
String name = su.getRequest().getParameter("name");
File file = su.getFiles().getFile(0);
file.saveAs("/path/" + fileName);

// Commons FileUpload (Servlet 版)
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
String name = null;
for (FileItem item : items) {
    if (item.isFormField()) {
        if ("name".equals(item.getFieldName())) name = item.getString("UTF-8");
    } else {
        String fileName = UUID.randomUUID() + "." + FilenameUtils.getExtension(item.getName());
        item.write(new File("/path/" + fileName));
    }
}

遷移優勢

  1. Maven 管理:中央倉庫直接引用,版本控制透明
  2. 社群支援:活躍維護、安全漏洞修補及時
  3. Spring 整合:無縫對接 MultipartFile、MultipartResolver
  4. 標準相容:Servlet 3.0+ Part API 互通
  5. 功能對等:大小限制、類型過濾、暫存管理、進度監聽皆支援

web.xml 配置

<servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>com.example.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet</url-pattern>
</servlet-mapping>

總結

SmartUpload 曾是功能強大的上傳組件,但因年久失修已不適合新專案採用。本文提供完整 Servlet 整合範例供舊系統維護參考。強烈建議新專案或重構專案採用 Apache Commons FileUpload 或 Spring Boot MultipartFile,獲得更好的生態支援、安全性與可維護性。

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