天天看點

struts2實作檔案下載下傳

1 使用Struts2控制檔案下載下傳 可能很多人會覺得,檔案下載下傳太簡單,直接在頁面上給出一個超級連結,該連結的href屬性等于要下載下傳檔案的檔案名,不就可以實作檔案下載下傳了嗎?大 部分時候的确可以實作檔案下載下傳,但如果該檔案的檔案名為中文檔案名,則會導緻下載下傳失敗;或者應用程式需要在讓使用者下載下傳之前進行進一步檢查,比如判斷使用者是 否有足夠權限來下載下傳該檔案等。 看下面的一個原始的下載下傳頁面代碼片段: <h1>原始的下載下傳</h1> <ul><li> <!-- 包含中文檔案名的下載下傳連結 --> 下載下傳Struts2的Logo:<a href="images/中.gif" target="_blank" rel="external nofollow" >下載下傳圖形檔案</a> </li><li> 下載下傳Struts2的Logo的壓縮檔案:<a href="images/struts-gif.zip" target="_blank" rel="external nofollow" >下載下傳壓縮檔案</a> </li></ul> 上面頁面的包含兩個下載下傳的超級連結,兩個連結的資源都是存在的,但因為第一個資源檔案的檔案名是中文檔案名,如果單擊第一個超級連結,将出現如下圖所示的頁面。 從圖中頁面中橢圓形框包圍的地方,我們看到被下載下傳的檔案名變成了包含大量%的字元串,很明顯,這種檔案名顯然無法取得需要下載下傳的檔案。 為了解決這個問題,我們使用Struts2的檔案下載下傳支援來下載下傳該檔案。

2 實作檔案下載下傳的Action Struts2的檔案下載下傳Action與普通的Action并沒有太大的不同,僅僅是該Action需要提供一個傳回InputStream流的方法,該輸入流代表了被下載下傳檔案的入口。該Action類的代碼如下: public class FileDownloadAction implements Action { //該屬性是依賴注入的屬性,該屬性可以在配置檔案中動态指定該屬性值 private String inputPath; //依賴注入該屬性值的setter方法 public void setInputPath(String value) { inputPath = value; } public InputStream getTargetFile() throws Exception { return ServletActionContext.getServletContext().getResourceAsStream(inputPath); } //處理使用者請求的execute方法,該方法傳回success字元串 public String execute() throws Exception { return SUCCESS; } } 從上面的Action中看到,該Action中包含了一個getTargetFile()方法,該方法傳回一個InputStream輸入流,這 個輸入流傳回的是下載下傳目标檔案的入口。該方法的方法名為getTargetFile,表明該Action有一個targetFile屬性來傳回下載下傳檔案。 一旦我們定義了該Action,就可通過該Action來實作檔案下載下傳。

3 配置Action 配置該檔案下載下傳的Action與配置普通的Action并沒有太大的不同,需要在配置普通Action的基礎之上,在加上額外的download的攔截器引用。 除此之外,關鍵是需要配置一個類型為stream的結果,配置stream類型的結果時需要指定如下四個屬性:  contentType:指定被下載下傳檔案的檔案類型。  inputName:指定被下載下傳檔案的入口輸入流。  contentDisposition:指定下載下傳的檔案名。  bufferSize:指定下載下傳檔案時的緩沖大小。 因為stream結果類型的邏輯視圖是傳回給用戶端一個輸入流,是以無需指定location屬性。 提示:配置stream類型的結果時,因為無需指定實際的顯示的實體資源,是以無需指定location屬性,隻需要指定inputName屬性,該屬性指向被下載下傳檔案。 下面是配置該下載下傳所用的Action類的配置檔案片段: <?xml version="1.0" encoding="GBK"?> <!-- 指定Struts2配置檔案的DTD資訊 --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <!-- 配置Struts2國際化資源檔案的baseName --> <constant name="struts.custom.i18n.resources" value="globalMessages"/> <!-- 配置Struts2應用的編碼集 --> <constant name="struts.i18n.encoding" value="GBK"/> <package name="lee" extends="struts-default"> <!-- 配置下載下傳的攔截器引用 --> <default-action-ref name="download"/> <action name="download" class="lee.FileDownloadAction"> <!-- 指定被下載下傳資源的位置 --> <param name="inputPath">/images/中.gif</param> <!-- 配置結果類型為stream的結果 --> <result name="success" type="stream"> <!-- 指定下載下傳檔案的檔案類型 --> <param name="contentType">image/gif</param> <!-- 指定下載下傳檔案的檔案位置 --> <param name="inputName">targetFile</param> <param name="contentDisposition">filename="struts.gif"</param> <!-- 指定下載下傳檔案的緩沖大小 --> <param name="bufferSize">4096</param> </result> </action> </package> </struts> 如果通過上面的Struts2提供檔案下載下傳支援來實作檔案下載下傳,就可以實作包含中文檔案名的檔案下載下傳。

上面的下載下傳的方式沒有辦法動态的給定檔案名,于是就将上面的方法進行了改進:

首先struts.xml配置檔案如下:

<!-- 檔案下載下傳2-->

	<action name="filedown" class="com.actions.FileDownActions">

		<param name="inputPath">/upload/</param>

		<result name="success" type="stream">

			<param name="contentType">image/gif</param>

			<param name="inputName">targetFile</param>

			<param name="contentDisposition">filename="download.gif"</param> 

			<param name="bufferSize">4096</param>

		</result>

	</action>      

再就是html中加入:

<a href="filedown.action?download=52415.gif" target="_blank" rel="external nofollow" >download</a>

下面給出FileDownActions的代碼:

package com.actions;



import java.io.InputStream;



import org.apache.struts2.ServletActionContext;



import com.opensymphony.xwork2.ActionSupport;



public class FileDownActions extends ActionSupport {

	private String download;

	private String inputPath;

	public String getInputPath() {

		return inputPath;

	}



	public void setInputPath(String inputPath) {

		this.inputPath = inputPath;

	}



	public String getDownload() {

		return download;

	}



	public void setDownload(String download) {

		this.download = download;

	}

	

	public InputStream getTargetFile() throws Exception 

	{ 

		return ServletActionContext.getServletContext().getResourceAsStream(inputPath+download); 

	} 

	public String execute(){

		return SUCCESS;

	}

}
           
通過上面的操作就可以實作檔案的下載下傳了