使用Struts控制文件下載 可能很多人會覺得文件下載太簡單直接在頁面上給出一個超級鏈接該鏈接的href屬性等於要下載文件的文件名不就可以實現文件下載了嗎?大部分時候的確可以實現文件下載但如果該文件的文件名為中文文件名則會導致下載失敗或者應用程序需要在讓用戶下載之前進行進一步檢查比如判斷用戶是否有足夠權限來下載該文件等
看下面的一個原始的下載頁面代碼片段 <h>原始的下載</h> <ul><li> <! 包含中文文件名的下載鏈接 > 下載Struts的Logo<a images/中gif>下載圖形文件</a> </li><li> 下載Struts的Logo的壓縮文件<a >下載壓縮文件</a> </li></ul> 上面頁面的包含兩個下載的超級鏈接兩個鏈接的資源都是存在的但因為第一個資源文件的文件名是中文文件名如果單擊第一個超級鏈接將出現如下圖所示的頁面 從圖中頁面中橢圓形框包圍的地方我們看到被下載的文件名變成了包含大量%的字符串很明顯這種文件名顯然無法取得需要下載的文件 為了解決這個問題我們使用Struts的文件下載支持來下載該文件
實現文件下載的Action Struts的文件下載Action與普通的Action並沒有太大的不同僅僅是該Action需要提供一個返回InputStream流的方法該輸入流代表了被下載文件的入口該Action類的代碼如下 public class FileDownloadAction implements Action { //該屬性是依賴注入的屬性該屬性可以在配置文件中動態指定該屬性值 private String inputPath; //依賴注入該屬性值的setter方法 public void setInputPath(String value) { inputPath = value; } /* 下載用的Action應該返回一個InputStream實例 該方法對應在result裡的inputName屬性值為targetFile */ public InputStream getTargetFile() throws Exception { return ServletActionContextgetServletContext()getResourceAsStream(inputPath); } //處理用戶請求的execute方法該方法返回success字符串 public String execute() throws Exception { return SUCCESS; } } 從上面的Action中看到該Action中包含了一個getTargetFile()方法該方法返回一個InputStream輸入流這 個輸入流返回的是下載目標文件的入口該方法的方法名為getTargetFile表明該Action有一個targetFile屬性來返回下載文件 一旦我們定義了該Action就可通過該Action來實現文件下載
配置Action 配置該文件下載的Action與配置普通的Action並沒有太大的不同需要在配置普通Action的基礎之上在加上額外的download的攔截器引用 除此之外關鍵是需要配置一個類型為stream的結果配置stream類型的結果時需要指定如下四個屬性 ? contentType指定被下載文件的文件類型 ? inputName指定被下載文件的入口輸入流 ? contentDisposition指定下載的文件名 ? bufferSize指定下載文件時的緩沖大小 因為stream結果類型的邏輯視圖是返回給客戶端一個輸入流因此無需指定location屬性 提示配置stream類型的結果時因為無需指定實際的顯示的物理資源所以無需指定location屬性只需要指定inputName屬性該屬性指向被下載文件 下面是配置該下載所用的Action類的配置文件片段 <?xml version= encoding=GBK?> <! 指定Struts配置文件的DTD信息 > <!DOCTYPE struts PUBLIC //Apache Software Foundation//DTD Struts Configuration //EN dtd> <struts> <! 配置Struts國際化資源文件的baseName > <constant name=strutscustominresources value=globalMessages/> <! 配置Struts應用的編碼集 > <constant name=strutsinencoding value=GBK/> <package name=lee extends=strutsdefault> <! 配置下載的攔截器引用 > <defaultactionref name=download/> <action name=download class=leeFileDownloadAction> <! 指定被下載資源的位置 > <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=strutsgif</param> <! 指定下載文件的緩沖大小 > <param name=bufferSize></param> </result> </action> </package> </struts> 如果通過上面的Struts提供文件下載支持來實現文件下載就可以實現包含中文文件名的文件下載
上面的下載的方式沒有辦法動態的給定文件名於是就將上面的方法進行了改進
首先strutsxml配置文件如下
view plaincopy to clipboardprint?
<! 文件下載>
<action name=filedown class=comactionsFileDownActions>
<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=downloadgif</param>
<param name=bufferSize></param>
</result>
</action>
<! 文件下載>
<action name=filedown class=comactionsFileDownActions>
<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=downloadgif</param>
<param name=bufferSize></param>
</result>
</action>再就是html中加入
<a >download</a>
下面給出FileDownActions的代碼
view plaincopy to clipboardprint?
package comactions;
import javaioInputStream;
import orgapachestrutsServletActionContext;
import comopensymphonyxworkActionSupport;
public class FileDownActions extends ActionSupport {
private String download;
private String inputPath;
public String getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
thisinputPath = inputPath;
}
public String getDownload() {
return download;
}
public void setDownload(String download) {
thisdownload = download;
}
public InputStream getTargetFile() throws Exception
{
return ServletActionContextgetServletContext()getResourceAsStream(inputPath+download);
}
public String execute(){
return SUCCESS;
}
}
package comactions;
import javaioInputStream;
import orgapachestrutsServletActionContext;
import comopensymphonyxworkActionSupport;
public class FileDownActions extends ActionSupport {
private String download;
private String inputPath;
public String getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
thisinputPath = inputPath;
}
public String getDownload() {
return download;
}
public void setDownload(String download) {
thisdownload = download;
}
public InputStream getTargetFile() throws Exception
{
return ServletActionContextgetServletContext()getResourceAsStream(inputPath+download);
}
public String execute(){
return SUCCESS;
}
}
view plaincopy to clipboardprint?
通過上面的操作就可以實現文件的下載了
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28254.html