一.單個文件上傳
文件上傳需要兩個jar包:

首先制作一個簡單的頁面,用於實現文件上傳
<h1>單個文件上傳</h1> <s:form action="upload.action" enctype="multipart/form-data" method="post" namespace="/"> <s:textfield name="title" lable="標題"></s:textfield> <s:file name="upload" lable="選擇文件"></s:file> <s:submit value="上傳文件"></s:submit> </s:form>
開發實現文件上傳的Action
package cn.action; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport{ //封裝上傳文件屬性 private File upload; //封裝上傳文件的類型 private String uploadContentType; //封裝上傳文件名稱 private String uploadFileName; //封裝文件上傳的路徑 private String savePath; public String execute(){ byte[] buffer=new byte[1024]; try { FileInputStream fis=new FileInputStream(getUpload()); FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()); int length=fis.read(buffer); while(length>0){ fos.write(buffer, 0, length); length=fis.read(buffer); } fos.flush(); fos.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("========================"); return SUCCESS; } public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } public String getSavePath() { return ServletActionContext.getServletContext().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } }
在Action中使用了三個屬性封裝文件信息
File類型的XXX屬性,與表單的File控件的name屬性一樣,用於封裝File控件對應的文件內容
String類型的xxxFileName屬性,該屬性名稱由前面的File類型屬性和FileName組合,是固定的語法,是封裝File控件對應文件的文件名
String類型的XXXContentType屬性,同樣由xxx屬性和ContentType組合而成,是固定語法,封裝File控件對應文件的文件類型
配置Action
<!-- 單個文件上傳 --> <action name="upload" class="cn.action.UploadAction"> <!-- 通過param參數設置保存目錄的路徑 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
效果圖:



二.多個文件上傳
只需在上傳Action中將原本處理單個文件的操作改成對集合操作即可。
其他的都跟單個上傳的一樣
頁面
<!-- 多個文件上傳 --> <action name="someupload" class="cn.action.SomeUploadAction"> <!-- 通過param參數設置保存目錄的路徑 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
開發實現文件上傳的Action
package cn.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class SomeUploadAction extends ActionSupport { //封裝上傳文件屬性 private File[] upload; //封裝上傳文件的類型 private String[] uploadContentType; //封裝上傳文件名稱 private String[] uploadFileName; //封裝文件上傳的路徑 private String savePath; public String execute() throws Exception{ byte[] buffer=new byte[1024]; for (int i = 0; i < upload.length; i++) { FileInputStream fis=new FileInputStream(getUpload()[i]); FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()[i]); int length=fis.read(buffer); while(length>0){ fos.write(buffer, 0, length); length=fis.read(buffer); } fos.flush(); fos.close(); fis.close(); } return SUCCESS; } public File[] getUpload() { return upload; } public void setUpload(File[] upload) { this.upload = upload; } public String[] getUploadContentType() { return uploadContentType; } public void setUploadContentType(String[] uploadContentType) { this.uploadContentType = uploadContentType; } public String[] getUploadFileName() { return uploadFileName; } public void setUploadFileName(String[] uploadFileName) { this.uploadFileName = uploadFileName; } public String getSavePath() { return ServletActionContext.getServletContext().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } }
配置Action
<!-- 多個文件上傳 --> <action name="someupload" class="cn.action.SomeUploadAction"> <!-- 通過param參數設置保存目錄的路徑 --> <param name="savePath">/upload</param> <result name="success">success.jsp</result> </action>
效果:



三.文件下載
文件下載需要InputStream,首先在文件下載Action中提供一個獲得InputStream的方法,通過輸入流可以獲取希望下載的文件內容
package cn.action; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class FileDownAction extends ActionSupport { //讀取下載文件的目錄 private String inputPath; //下載文件的文件名 private String fileName; //讀取下載文件的輸入流 private InputStream inputStream; //下載文件的類型 private String conetntType; public String execute(){ return SUCCESS; } public String getInputPath() { return inputPath; } public void setInputPath(String inputPath) { this.inputPath = inputPath; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } //創建InputStream輸入流 public InputStream getInputStream() throws Exception { String path=ServletActionContext.getServletContext().getRealPath(inputPath); BufferedInputStream stream = new BufferedInputStream(new FileInputStream(path+"\\"+fileName)); return stream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String getConetntType() { return conetntType; } public void setConetntType(String conetntType) { this.conetntType = conetntType; } }
通過Context得到下載文件的實際路徑,構建一個InputStream輸入流實現文件的下載讀取。
在配置文件中,同樣對Action進行配置,並對stream結果類型的參數進行設置。
<!-- download指定的Action --> <action name="download" class="cn.action.FileDownAction"> <param name="inputPath">/upload</param> <result name="success" type="stream"> <param name="contentType">application/octet-stream</param> <param name="inputName">inputStream</param> <param name="contentDisposition"> attachment;filename="${fileName}" </param> <param name="bufferSize">4096</param> </result> </action>
ContentType參數決定了下載文件的類型,不同的文件類型對應的參數值也是不同的。

通常情況下,ContentType參數直接設置為application/octet-stream即可。
contentDisposition參數由兩部分組成,前面的部分表示處理文件的形式,如attachement表示在下載時彈出對話框,提出用戶保存或直接打開該文件;而后一部分表示下載文件的文件名稱。兩部分之間用“;”進行分隔。
然后開發一個簡單的下載頁面,在頁面中設置一個超鏈接,通過超鏈接請求下載Action
<h1>文件下載</h1> <s:a href="download.action?fileName=2.jpg">點擊此處下載文件</s:a>
效果:


