SmartUpload 是早期商業級文件上傳組件,功能豐富 (支援進度條、大檔案分片、圖片縮圖等),但已停止維護、官網關閉、無 Maven 中央倉庫。現代專案強烈建議改用 Apache Commons FileUpload 或 Spring MultipartFile。本文僅供維護舊系統參考。
jspsmartupload.jar (需手動下載、安裝至本地倉庫或放入 WEB-INF/lib)<%@ 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>
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);
}
}
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
}
}
| Commons FileUpload | SmartUpload | 說明 |
|---|---|---|
| DiskFileItemFactory | SmartUpload (內建) | 工廠/解析器合一 |
| 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() | 檔案大小 |
smart.setMaxFileSize(1024 * 1024 * 5); // 5MB 單檔
smart.setTotalMaxFileSize(1024 * 1024 * 20); // 20MB 總計
smart.setAllowedFilesList("jpg,jpeg,png,gif,pdf"); // 白名單
smart.setDeniedFilesList("exe,bat,sh,jsp,php,asp"); // 黑名單
file.saveAs("/upload/" + fileName); // 會自動建立 upload 目錄
smart.setSizeThreshold(1024 * 1024); // 1MB 以上寫磁碟暫存
// 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));
}
}
MultipartFile、MultipartResolverPart API 互通<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,獲得更好的生態支援、安全性與可維護性。