【SSH2(實踐篇)】--Struts2檔案上傳下載例項

zhang_xinxiu發表於2014-05-07

       上篇文章又一次回顧了Struts2的執行機制,對它的執行步驟做了一步步的解析,這個解析不但再一次理清了Struts2的使用方法,而且對它的對映機制進行了深入的解析,並在最後通過一個例項來介紹了Struts2的一種使用方法,這裡將做一個有關檔案上傳下載的例項。


一、檔案上傳


       Struts2並沒有提供檔案上傳的元件,所以想要實現上傳的功能就必須通過第三方元件來實現,在Struts2引用的jar中包含了檔案上傳的元件,它是通過commons-fileupload.jar和commons-io.jar來實現的。這其中的處理細節不需要太懂,在使用中慢慢思考就可以做到靈活運用。


  1、首先編寫Action類

       該類名稱為downloadAction.java,必須在該類中引入java.io,檔案上傳的核心實現使用的還是java的資料流io操作。

package com.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 uploadAction extends ActionSupport {
	
	private File file;
	
	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	//檔名稱
	private String fileFileName;
	
	//檔案型別
	private String fileContentType;
	//注意:檔名稱和檔案型別的名稱字首必須相同,
	
	@Override
	public String execute() throws Exception{	
		
		//獲取需要上傳檔案的檔案路徑
		File uploadFile=new File(ServletActionContext.getServletContext().getRealPath("uploadFile"));
		//判斷檔案是否上傳,如果上傳的話將會建立該目錄
		if(!uploadFile.exists()){
			uploadFile.mkdir();	//建立該目錄
		}
		
		//第一種檔案上傳的方法
		//宣告檔案輸入流,為輸入流指定檔案路徑
		FileInputStream input=new FileInputStream(file);
		//獲取輸出流,獲取檔案的檔案地址及名稱
		FileOutputStream out=new FileOutputStream(uploadFile + "\\" +fileFileName);
		
		try{
			byte[] b=new byte[1024];//每次寫入的大小
			int i=0;
			while((i=input.read(b))>0){
				out.write(b,0,i);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			input.close();
			out.close();
		}
		
		
		
		//第二種檔案上傳的方法
		//FileUtils.copyFile(upload,new File(uploadFile+"\\"+uploadFileName));
		//FileUtils.copyFile(upload,new File(uploadFile,uploadFileName));
		
		//第三種方法
//		BufferedReader bReader=new BufferedReader(new InputStreamReader(new FileInputStream(upload)));
//		BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(uploadFile+"\\"+uploadFileName)));
		
//		try{
//			char[] str=new char[1024];
//			int i=0;
//			while((i=bReader.read(str))>0){
//				bWriter.write(str,0,i); 
//			}
//		}catch(Exception e){
//			e.printStackTrace();
//		}finally{
//			bReader.close();
//			bWriter.close();
//			uploadFile.delete();
//		}
		
		return "success";
	}

}

        Action類中需要注意的是檔名和檔案型別的命名都是有要求的,檔名和檔案型別的字首必須是檔案變數,並且要和jsp頁面中新增的檔名稱一致,如上例中的jsp標籤為:<input type='File' name='file'>,在Action類中的檔名稱和檔案型別必須相應為fileXXX和fileXXX。另外也可以在該Action類中配置其它上傳屬性,如:可以通過maximumSize指定上傳檔案的大小,allowedTypes執行上傳檔案的型別。

       上面的Action類指定了三種上傳方法,它們操作的核心還是java.io,通過資料流的讀入和寫出來實現檔案的上傳。其中第一種和第三種採用的是java.io流操作,而第二種採用的是common.io流操作。


   2、struts2.xml相應的action配置

       action類編寫完成後,接下來要把它配置到相應的action標籤中,這樣在執行action時會根據註冊類執行內部的方法。具體配置方法如下例項。

<package name="upload" namespace="/file" extends="struts-default">
	<action name="upload" class="uploadAction">
		<result name="success">/success.jsp</result>
		<result name="error">/error.jsp</result>
		<result name="input">/index.jsp</result>
		<param name="savePath">/upload</param>
	</action>
</package>

   3、最後配置相應的jsp頁面

        在配置時需要注意的是檔案的編碼格式,需要改成multipart/form-data型別,是指把檔案及檔案的內容都提交,另外enctype還有兩個屬性值分別是text/plain,指定了表單是以文字的方式進行提交;application/x-www-form-urlencoded這是預設的編碼方式,提交時,只提交表單域的value屬性值。

<body>
	<form action="file/upload" method="post" enctype="multipart/form-data">
		<input type="file" name="upload">
		<input type="submit" name="btnUpload" value="上傳">
	</form>
</body>

     最後提交,檢視提交結果,提交後的檔案預設存放在.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\專案名稱\uploadFile下,所以在編寫action類時需要獲取檔案上傳的路徑使用的是getRealPath("uploadFile")。


二、檔案下載


      相較上傳,檔案的下載編寫起來相交就簡單多了,首先也需要新增下載的action類,然後配置struts.xml中的action,最後在jsp中新增連結標籤。


  1、新增下載action類

       新增的action類指定要注意獲取檔案的輸出路徑,通過獲取輸出流來獲取檔案的路徑。

package com.action;

import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class downloadAction extends ActionSupport {
	
	private InputStream fileInput;
	private String fileName;

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public InputStream getFileInput() {
		return ServletActionContext.getServletContext().getResourceAsStream("upload\\"+fileName);
	}

	public void setFileInput(InputStream fileInput) {
		this.fileInput = fileInput;
	}
	
	public String execute() throws Exception{
		fileInput=ServletActionContext.getServletContext().getResourceAsStream("upload\\"+fileName);
		return "success";
	}
}

   2、配置struts.xml標籤

        在配置時結果型別要指定type型別,將它賦值為stream,並新增屬性下面的屬性,該屬性同樣可以配置到攔截器中,在攔截器中指定配置的檔案。

<action name="download" class="com.action.downloadAction">
    	<result name="success" type="stream">
		<param name="inputName">fileInput</param>
		<param name="contentDispostion">attachment;filename="$(fileName)"</param>
	</result>
</action>


    3、jsp頁面程式碼

       jsp程式碼就很簡單了,不多說看程式碼。

<body>
	<a href="file/download">123.txt</a>
</body>

結語


        通過使用檔案的上傳下載功能來熟悉Struts2的使用方法,並瞭解Servlet請求的基本用法,為以後深入學習Servlet打下基礎。struts的檔案上傳和下載使用的是io流操作完成的,可以使用java.io流,同樣可以使用第三方的common.io流實現,有關多檔案上傳的問題將會在下篇文章中討論。

相關文章