Struts2 文件上傳下載是 Web 開發高頻需求。本文提供完整項目結構、上傳/下載 Action 代碼、struts.xml 配置、中文文件名編碼解決方案、大文件流式傳輸優化等生產級實現方案。
src/
com/
UploadAction.java
DownLoadAction.java
web/
upload.jsp
download.jsp
struts.xml
public class UploadAction extends ActionSupport {
private File[] uploadFile; // 上傳文件
private String[] uploadFileFileName; // 原始文件名
private String[] uploadFileContentType; // MIME 類型
private String savePath = "file/"; // 保存相對路徑
// Getter/Setter 省略
public String execute() {
for (int i = 0; i < uploadFile.length; i++) {
File dest = new File(ServletActionContext.getServletContext().getRealPath(savePath), uploadFileFileName[i]);
copy(uploadFile[i], dest);
}
return SUCCESS;
}
private static void copy(File src, File dst) {
try (InputStream in = new BufferedInputStream(new FileInputStream(src));
OutputStream out = new BufferedOutputStream(new FileOutputStream(dst))) {
byte[] buffer = new byte[16 * 1024];
int len;
while ((len = in.read(buffer)) > 0) out.write(buffer, 0, len);
} catch (IOException e) { throw new RuntimeException(e); }
}
}
public class DownLoadAction extends ActionSupport {
private String fileName; // 請求參數文件名
private String savePath = "file/";
public String execute() {
this.fileName = ServletActionContext.getRequest().getParameter("fileName");
return SUCCESS;
}
// 提供 InputStream 給 stream Result 類型使用
public InputStream getDownloadFile() throws UnsupportedEncodingException {
String decoded = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
return ServletActionContext.getServletContext().getResourceAsStream(savePath + decoded);
}
// Content-Disposition 編碼處理
public String getDownloadChineseFileName() {
try {
return new String(fileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) { return fileName; }
}
}
<package name="file" namespace="/file" extends="struts-default">
<action name="upload" class="com.UploadAction">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">10485760</param> <!-- 10MB -->
</interceptor-ref>
<result name="success">/upload_success.jsp</result>
</action>
<action name="download" class="com.DownLoadAction">
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">downloadFile</param> <!-- 對應 getDownloadFile() -->
<param name="contentDisposition">attachment;filename="${downloadChineseFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
</package>
fileUpload 攔截器,自動注入 File[]/String[] 屬性type="stream" Result,配合 getXxx() 方法輸出流ISO8859-1 → UTF-8,響應頭 UTF-8 → ISO8859-1BufferedInputStream/OutputStream)避免 OOM