Struts 2 內置 FileUploadInterceptor(屬於 defaultStack)支援基於表單的文件上傳。上傳文件先存臨時目錄,Action 需處理或移動到永久目錄,否則可能丟失。
enctype="multipart/form-data"(必須)myFile)對應 Action 的三個屬性:File myFile(文件對象)、String myFileContentType(MIME 類型)、String myFileFileName(原始文件名)struts.multipart.maxSize 限制最大上傳大小(默認 2MB)<form action="Upload.action" method="post" enctype="multipart/form-data">
<label for="myFile">你要上傳的文件</label>
<input type="file" name="myFile" /><br>
<input type="submit" value="上傳"/>
</form>
public class FileUploadAction extends ActionSupport {
private File myFile;
private String myFileContentType;
private String myFileFileName;
private String destPath = "e:/upload/";
// getter/setter 省略...
@Override
public String execute() throws Exception {
try {
System.out.println("Src File name: " + myFile);
System.out.println("我的文件名: " + myFileFileName);
System.out.println("我的文件類型: " + myFileContentType);
File destFile = new File(destPath, myFileFileName);
FileUtils.copyFile(myFile, destFile); // 需 commons-io
} catch (IOException e) {
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
}
<constant name="struts.multipart.maxSize" value="10701096" /> <!-- 10MB -->
<package name="upload" namespace="/" extends="struts-default">
<action name="Upload" class="com.oumyye.FileUpload.FileUploadAction">
<result name="success">/success.jsp</result>
<result name="input">/index.jsp</result>
</action>
<!-- 下載配置見下 -->
</package>
<h2>文件下載內容:</h2><br/>
Dream.jpg: <a href="FileDownload.action">點擊下載</a><br/>
InputStream)public class FileDownload extends ActionSupport {
private String fileName;
public String getFileName() { return fileName; }
public void setFileName(String fileName) { this.fileName = fileName; }
public InputStream getDownloadFile() throws Exception {
this.fileName = "hello.jpg"; // 實際可從參數獲取
return ServletActionContext.getServletContext()
.getResourceAsStream("upload/" + this.fileName);
}
@Override public String execute() { return SUCCESS; }
}
type="stream")<action name="FileDownload" class="com.oumyye.action.FileDownload">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="contentDisposition">attachment;fileName="${fileName}"</param>
<param name="inputName">downloadFile</param> <!-- 對應 getDownloadFile() -->
<param name="bufferSize">1024</param>
</result>
</action>
Can not find a java.io.InputStream with the name [downloadFile] in the invocation stack.
原因 1:文件路徑錯誤,getResourceAsStream() 返回 null。打印流對象驗證。
原因 2:Action 缺少 getDownloadFile() 方法(需與 inputName 參數對應)。
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
enctype + 三屬性約定 + FileUploadInterceptor + FileUtils.copyFile 持久化。InputStream + type="stream" Result + contentDisposition 觸發瀏覽器下載。