在作B/S系統時,一般會涉及到上傳文件和下載文件,在沒接struts2框架以前,咱們都是使用apache下面的commons子項目的FileUpload組件來進行文件的上傳,可是那樣作的話,代碼看起來比較繁瑣,並且不靈活,在學習了struts2後,struts2爲文件上傳下載提供了更好的實現機制,在這裏我分別就單文件上傳和多文件上傳的源代碼進行一下講解,這裏須要導入文件下載上傳的兩個jar文件,一個是commons-fileupload-1.2.2.jar,另外一個是commons-io-2.0.1.jar前端
struts2單文件上傳:apache
首先是一個jsp文件上傳頁面,這個比較簡單,就是一個表單,裏面有個文件上傳框數組
<!--在進行文件上傳時,表單提交方式必定要是post的方式,由於文件上傳時二進制文件可能會很大,還有就是enctype屬性,這個屬性必定要寫成multipart/form-data, 否則就會以二進制文本上傳到服務器端--> <s:form action="uploadOne" enctype="multipart/form-data" method="POST"> <s:file name="upload" label="選擇文件"/><br> <s:submit name="submit" value="上傳文件"/> </s:form>
接下來是uploadOne部分代碼,由於struts2對上傳和下載都提供了很好的實習機制,因此在action這段咱們只須要寫不多的代碼就行:瀏覽器
public class uploadOne extends ActionSupport { //獲取文件 private File upload; //獲取文件的類型 private String uploadContentType; //上傳文件的名稱 private String uploadFileName; //獲取文件上傳的路徑 private String path; @Override public String execute() throws Exception { byte[] bytes=new byte[1024]; //讀取文件 FileInputStream fis=new FileInputStream(getUpload()); //寫入文件,並設置保存目錄的路徑 FileOutputStream fos=new FileOutputStream(getPath()+"\\"+getUploadFileName()); int length=fis.read(bytes); while (length>0){ fos.write(bytes,0,length); length=fis.read(bytes); } fos.close(); fos.flush(); fis.close(); return SUCCESS; } //獲取上傳文件的保存路徑 //經過讀取存放目錄得到保存路徑 public String getPath() { return ServletActionContext.getServletContext().getRealPath(path); } public void setPath(String path) { this.path = path; } 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; } }
首先咱們要清楚一點,這裏的upload並非真正指代jsp上傳過來的文件,當文件上傳過來時,struts2首先會尋找struts.multipart.saveDir(這個是在default.properties裏面有)這個name所指定的存放位置,咱們能夠新建一個struts.properties屬性文件來指定這個臨時文件存放位置,若是沒有指定,那麼文件會存放在tomcat的apache-tomcat-7.0.29\work\Catalina\localhost\目錄下,而後咱們能夠指定文件上傳後的存放位置,經過輸出流將其寫到流裏面就好了,這時咱們就能夠在文件夾裏看到咱們上傳的文件了。tomcat
struts.xml配置服務器
<action name="uploadOne" class="cn.happy.action.uploadOne"> <!--經過param參數設置保存目錄的路徑--> <param name="path">/upload</param> <result name="success">oneUpload/two.jsp</result> </action>
文件上傳後咱們還須要將其下載下來,其實struts2的文件下載原理很簡單,就是定義一個輸入流,而後將文件寫到輸入流裏面就行,關鍵配置仍是在struts.xml這個配置文件裏配置:app
FileDownloadAction代碼以下:框架
//讀取下載文件的目錄 private String inputPath; //下載文件的文件名 private String fileName; //讀取下載文件的輸入流 private InputStream inputStream; //下載文件的類型 private String contntType; //建立InputStream輸入流 public InputStream getInputStream() throws FileNotFoundException { String path= ServletActionContext.getServletContext().getRealPath(inputPath); return new BufferedInputStream(new FileInputStream(path+"\\"+fileName)); } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } 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; }
struts.xml配置jsp
<action name="first" class="cn.happy.action.FileAction"> <param name="inputPath">/upload</param> <result name="success" type="stream"> <!-- 指定下載文件的內容類型,text/plain是默認類型 --> <param name="contntType">application/octet-stream</param> <!-- inputName默認值是inputStream,若是action中用於讀取 下載文件內容的屬性名是inputStream,那麼能夠省略這個參數 --> <param name="inputName">inputStream</param> <!--動態獲取文件名,從Action中的取得filename--> <param name="contentDisposition"> attachment;filename="${fileName}" </param> <param name="bufferSize">2048</param> </result>
struts.xml配置文件有幾個地方咱們要注意,首先是result的類型,之前咱們定義一個action,result那裏咱們基本上都不寫type屬性,由於其默認是請求轉發(dispatcher)的方式,除了這個屬性通常還有redirect(重定向)等這些值,在這裏由於咱們用的是文件下載,因此type必定要定義成stream類型,告訴action這是文件下載的result,result元素裏面通常還有param子元素,這個是用來設定文件下載時的參數,inputName這個屬性就是獲得action中的文件輸入流,名字必定要和action中的輸入流屬性名字相同,而後就是contentDisposition屬性,這個屬性通常用來指定咱們但願經過怎麼樣的方式來處理下載的文件,若是值是attachment,則會彈出一個下載框,讓用戶選擇是否下載,若是不設定這個值,那麼瀏覽器會首先查看本身可否打開下載的文件,若是能,就會直接打開所下載的文件,(這固然不是咱們所須要的),另一個值就是filename這個就是文件在下載時所提示的文件下載名字。ide
contentDispoistion參數由兩部分組成,前面的部分表示處理文件的形式,如attachement表示在下載是彈出對話框,提示用戶保存或者直接打開該文件;然後一部分表示下載文件的文件名稱。兩部分之間以;進行分隔。
在配置完這些信息後,咱們就能過實現文件的下載功能了。
下載文件jsp頁面
<a href="first?fileName=ehcache.xml">點擊此處下載文件</a>
struts2多文件上傳:
其實多文件上傳和單文件上傳原理同樣,單文件上傳過去的是單一的File,多文件上傳過去的就是一個List<File>集合或者是一個File[]數組,首先咱們來看一下前端jsp部分的代碼,
<s:form action="more" enctype="multipart/form-data" method="POST"> <s:file name="upload" label="選擇文件"/><br> <s:file name="upload" label="選擇文件"/><br> <s:submit name="submit" value="上傳文件"/> </s:form>
file的名字必須都命名成upload才行,而後處理多文件上傳的action代碼以下:
public class MoreUploadAction extends ActionSupport{ //獲取文件 private List<File> upload; //獲取文件的類型 private List<String> uploadContentType; //上傳文件的名稱 private List<String> uploadFileName; //獲取文件上傳的路徑 private String path; @Override public String execute() throws Exception { byte[] bytes=new byte[1024]; int index=0; for (File item:upload) { FileInputStream inputStream=new FileInputStream(item); FileOutputStream output=new FileOutputStream(getPath()+"\\"+getUploadFileName().get(index++)); int length=inputStream.read(bytes); while (length>0){ output.write(bytes,0,length); length=inputStream.read(bytes); } output.flush(); output.close(); inputStream.close(); } return SUCCESS; } //獲取上傳文件的保存路徑 //經過讀取存放目錄得到保存路徑 public String getPath() { return ServletActionContext.getServletContext().getRealPath(path); } public void setPath(String path) { this.path = path; } public List<File> getUpload() { return upload; } public void setUpload(List<File> upload) { this.upload = upload; } public List<String> getUploadContentType() { return uploadContentType; } public void setUploadContentType(List<String> uploadContentType) { this.uploadContentType = uploadContentType; } public List<String> getUploadFileName() { return uploadFileName; } public void setUploadFileName(List<String> uploadFileName) { this.uploadFileName = uploadFileName; }
struts.xml配置
<!--多文件上傳--> <action name="more" class="cn.happy.action.MoreUploadAction"> <!--經過param參數設置保存目錄的路徑--> <param name="path">/upload</param> <result name="success">moreUpload/two.jsp</result> </action>
這樣一樣將其寫到一個輸出流裏面,這樣咱們就能夠在文件夾裏看到上傳的多個文件了
接下來的文件下載就和剛纔的文件下載如出一轍,struts.xml也是同樣的,這裏就再也不重複了
總結:總的來講,struts2提供的文件上傳下載機制簡化了咱們不少代碼,咱們能夠在之後的項目中使用該機制,一樣咱們也可使用FileUpload組件來進行文件的上傳,這個都是因我的愛好決定!