在 JSP 頁面中定義一個文件上傳輸入框,注意表單必須設置 enctype="multipart/form-data":
<tr>
<td align="right" bgcolor="#F5F8F9"><b>附件:</b></td>
<td bgcolor="#FFFFFF">
<input type="file" name="upload" />
</td>
<td bgcolor="#FFFFFF"> </td>
</tr>
在 BaseAction 中聲明接收上傳文件所需的屬性:
public class BaseAction extends ActionSupport {
protected List<File> upload;
protected List<String> uploadContentType; // 文件類型
protected List<String> uploadFileName; // 文件名
protected String savePath; // 保存路徑
}
在具體 Action 中實現上傳邏輯,遍歷文件列表並寫入磁盤:
public void uploadAccess(List<File> upload) {
try {
if (null != upload) {
for (int i = 0; i < upload.size(); i++) {
String path = getSavePath() + getUploadFileName().get(i);
item.setAccessory(getUploadFileName().get(i));
FileOutputStream fos = new FileOutputStream(path);
FileInputStream fis = new FileInputStream(getUpload().get(i));
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fis.close();
fos.close();
}
}
} catch (Exception e) {
logger.error("上傳附件失敗。", e);
}
}
配置 fileUpload 攔截器限制文件類型與大小:
<action name="itemRDAction_*" class="itemRDAction" method="{1}">
<param name="savePath">e:upload</param>
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">
application/octet-stream,image/pjpeg,image/bmp,image/jpg,image/png,image/gif,image/jpeg,
application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,
application/vnd.ms-excel
</param>
<param name="fileUpload.maximumSize">8000000</param>
</interceptor-ref>
<result name="show_item_rd_upd">/WEB-INF/jsp/page_item/updItem_rd.jsp</result>
<result name="show_item_rd_list">/WEB-INF/jsp/page_item/listItem_rd.jsp</result>
<result name="show_item_rd_push">/WEB-INF/jsp/page_item/pushItem_rd.jsp</result>
</action>
使用 JSTL 判斷附件是否存在並生成下載連結:
<tr>
<td width="20%" align="right" bgcolor="#F5F8F9"><b>附件:</b></td>
<td width="40%" bgcolor="#FFFFFF">
<div>${item.accessory}</div>
<c:if test="${!empty item.accessory}">
<div class="btn_img"><a href="download.action?filename=${item.accessory}">下載</a></div>
</c:if>
</td>
<td width="40%" bgcolor="#FFFFFF"> </td>
</tr>
繼承 BaseAction,實現 getInputStream() 返回文件輸入流,並處理中文文件名編碼:
@Controller("downloadAction")
@Scope("prototype")
public class DownloadAction extends BaseAction {
private String filename;
private InputStream inputStream;
private String savePath;
private String mimeType;
public InputStream getInputStream() {
try {
String path = getSavePath() + "//" + new String(filename.getBytes("ISO8859-1"), "utf-8");
mimeType = ServletActionContext.getServletContext().getMimeType(path) + ";charset=UTF-8";
inputStream = new FileInputStream(path);
String agent = ServletActionContext.getRequest().getHeader("USER-AGENT");
if (null != agent) {
if (-1 != agent.indexOf("Firefox")) {
mimeType = mimeType.replace("UTF-8", "ISO8859-1");
} else {
filename = new String(filename.getBytes("ISO8859-1"), "utf-8");
filename = java.net.URLEncoder.encode(filename, "UTF-8");
}
}
} catch (Exception e) {
logger.error("下載文件信息失敗。", e);
}
return inputStream;
}
// getter/setter 省略
}
<action name="download" class="downloadAction">
<param name="savePath">E:/upload</param>
<result type="stream">
<param name="contentType">${mimeType}</param>
<param name="contentDisposition">attachment;filename="${filename}"</param>
<param name="inputName">inputStream</param>
</result>
</action>
上傳大文件時出現錯誤:the request was rejected because its size exceeds the configured maximum。
struts.properties 中添加 struts.multipart.saveDir=/temp。struts.properties 或 struts.xml 中設置 struts.multipart.maxSize(單位字節)。struts.xml 中為具體 Action 顯式引用 fileUpload 攔截器並設置 maximumSize,同時配置 input 結果頁面。addActionError 方法,解析異常信息並設置自定義錯誤消息,前端通過 <s:fielderror/> 或 JS 彈窗顯示。struts.multipart.maxSize:控制整個項目允許的最大請求大小,默認 2MB。fileUpload.maximumSize:單個 Action 級別的文件大小限制,必須小於 struts.multipart.maxSize。File too large;超過 struts.multipart.maxSize 則直接報錯。通過自定義攔截器棧 myDefaultStack 在 fileUpload 攔截器中設置 allowedTypes 參數,然後在 <package> 中設置為默認攔截器棧,或在具體 Action 中引用。
<interceptors>
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/png,image/gif,image/jpeg</param>
</interceptor-ref>
... 其他攔截器 ...
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack" />
注意:上傳表單必須包含 enctype="multipart/form-data",否則會直接進入 input 結果。