Struts2 透過 fileUpload 攔截器 封裝 Apache Commons FileUpload,自動將表單 multipart/form-data 解析為 Action 屬性。
method="post"enctype="multipart/form-data"<input type="file" name="file1">| 屬性名 | 型別 | 說明 |
|---|---|---|
file1 | File | 上傳檔案暫存路徑 |
file1FileName | String | 原始檔名 |
file1ContentType | String | MIME 類型 |
<package name="upload" extends="struts-default">
<action name="fileUploadAction" class="com.example.FileUploadAction">
<interceptor-ref name="defaultStack">
<!-- 限制副檔名 -->
<param name="fileUpload.allowedExtensions">txt,jpg,pdf</param>
<!-- 限制 MIME 類型(與副檔名取交集) -->
<param name="fileUpload.allowedTypes">text/plain,image/jpeg,application/pdf</param>
</interceptor-ref>
<result name="success">/upload/success.jsp</result>
<result name="input">/upload/error.jsp</result> <!-- 驗證失敗導向 -->
</action>
</package>
<constant name="struts.multipart.maxSize" value="31457280" /> <!-- 30MB -->
public class FileUploadAction extends ActionSupport {
private File file1;
private String file1FileName;
private String file1ContentType;
// Getter/Setter 省略
@Override
public String execute() {
String savePath = ServletActionContext.getServletContext().getRealPath("/upload");
File destDir = new File(savePath);
if (!destDir.exists()) destDir.mkdirs();
File destFile = new File(destDir, file1FileName);
FileUtils.copyFile(file1, destFile); // Commons IO
return SUCCESS;
}
}
<%@ taglib uri="/struts-tags" prefix="s" %>
<body>
<s:fielderror /> <!-- 自動顯示 fileUpload 攔截器產生的錯誤 -->
</body>
<package name="download" extends="struts-default">
<action name="down_*" class="com.example.DownAction" method="{1}">
<result name="list">/download/list.jsp</result>
<result name="download" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param> <!-- 對應 getInputStream() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
</package>
<c:forEach var="fileName" items="${fileNames}" varStatus="vs">
<tr>
<td>${vs.count}</td>
<td>${fileName}</td>
<td>
<c:url var="url" value="down_download">
<c:param name="fileName" value="${fileName}" />
</c:url>
<a href="${url}">下載</a>
</td>
</tr>
</c:forEach>
public class DownAction extends ActionSupport {
private String fileName;
// Setter 處理中文編碼
public void setFileName(String fileName) {
try {
this.fileName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public String list() {
String path = ServletActionContext.getServletContext().getRealPath("/upload");
File dir = new File(path);
String[] names = dir.list();
ActionContext.getContext().put("fileNames", names);
return "list";
}
public String download() { return "download"; }
// StreamResult 會自動呼叫 getInputStream()
public InputStream getInputStream() {
return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
}
// 下載時顯示的檔名(瀏覽器另存為對話框)
public String getDownloadFileName() {
try {
return URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
webapp/upload 並確保寫入權限struts.multipart.maxSize 並考慮分片上傳allowedExtensions/allowedTypes,防止惡意腳本上傳