今天學習了如何用struts實現文件下載的功能,可以將服務器的文件下載到客戶端。
其實不用struts也可以實現下載,可以直接用一個鏈接,href里面寫文件的目錄。如:
1 <a href="download/123.rar">123.rar</a>
這種方法簡單,不過它只能下載壓縮文件,而其他一些文件如文本文件、圖片等都會直接在頁面上面顯示出來而不會下載到客戶端,所以此方法不可取。
下面介紹另一種方法,也就是用struts實現文件的下載。首先,在WebRoot目錄下面建一個文件夾download,可以將文件上傳到這個目錄下面。下載文件也從該目錄下面下載。然后新建一個TestAction類,代碼如下(struts的配置這里就不講了):
1 public class TestAction extends ActionSupport{ 2 3 public String fileLoad() throws IOException{ 4 String fileName = ServletActionContext.getRequest().getParameter("fileName"); 5 //要處理中文亂碼問題 6 fileName = new String(fileName.getBytes("iso8859-1"),"utf-8"); 7 //要下載的哪個文件 8 String path = ServletActionContext.getServletContext().getRealPath("/");//得到項目的根目錄 9 InputStream is = new FileInputStream(path+"/download/"+fileName); 10 11 //下載到哪里?客戶端 12 HttpServletResponse response = ServletActionContext.getResponse(); 13 OutputStream os = response.getOutputStream(); 14 //彈出下載的框filename:提示用戶下載的文件名 15 response.addHeader("content-disposition", "attachment;filename="+java.net.URLEncoder.encode(fileName,"utf-8")); 16 17 byte[] b = new byte[1024]; 18 int size = is.read(b); 19 while(size>0){ 20 os.write(b,0,size); 21 size = is.read(b); 22 } 23 is.close(); 24 os.close(); 25 return null; 26 } 27 28 }
index.jsp的內容如下:
1 <a href="test!fileLoad.action?fileName=A.java">A.java</a> 2 3 <a href="test!fileLoad.action?fileName=jquery.txt">jquery.txt</a> 4 5 <a href="test!fileLoad.action?fileName=中文.txt">中文.txt</a>
文件下載分為兩步:讀文件、寫文件。從服務器讀取,然后寫到客戶端去,所以需要InputStream和OutputStream。然后設置content-disposition彈出下載提示框,提示用戶下載的文件名和從何處下載的。下面一段代碼是讀寫文件的金典代碼,我也不多講了!
1 byte[] b = new byte[1024]; 2 int size = is.read(b); 3 while(size>0){ 4 os.write(b,0,size); 5 size = is.read(b); 6 }
實現下載功能要注意:因為是用鏈接傳過來的文件名,所以必須處理中文亂碼問題。
以上方法實現下載功能沒有使用struts2里面自帶的文件下載。下面使用struts2自帶的方法實現文件下載功能。
struts.xml配置如下:
1 <struts> 2 <package name="com.action" extends="struts-default"> 3 <action name="download" class="com.action.FileLoadAction"> 4 <result name="success" type="stream"> 5 <param name="contentType">application/txt;</param> 6 <param name="inputName">downloadFile</param> 7 <param name="bufferSize">2048</param> 8 </result> 9 </action> 10 </package> 11 </struts>
FileLoadAction.java類
1 public class FileLoadAction extends ActionSupport{ 2 private String fileName; 3 4 public String getFileName() { 5 return fileName; 6 } 7 public void setFileName(String fileName) throws UnsupportedEncodingException { 8 this.fileName = new String(fileName.getBytes("iso8859-1"),"utf-8"); 9 } 10 public InputStream getDownloadFile() throws UnsupportedEncodingException, FileNotFoundException{ 11 //attachment為進行文件保存,這個時候還可以附件另一個參數filename表示保存時的缺省名稱 12 //inline為在線打開,不進行保存 13 ServletActionContext.getResponse().setHeader("Content-Disposition","attachment;fileName="+ java.net.URLEncoder.encode(fileName, "UTF-8")); 14 HttpServletResponse response = ServletActionContext.getResponse(); 15 return new FileInputStream("d:/"+this.getFileName()); 16 } 17 public String downloadFile(){ 18 return SUCCESS; 19 } 20 }
index.jsp代碼如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <%@taglib prefix="s" uri="/struts-tags" %> 3 4 <s:url value="download.action" var="url"> 5 <s:param name="fileName">中文.txt</s:param> 6 </s:url> 7 <a href="${url }">點擊下載</a>
action特殊的地方在於result的類型是一個流(stream),配置stream類型的結果時,因為無需指定實際的顯示的物理資源,所以無需指定location屬性,只需要指定inputName屬性,該屬性指向被下載文件的來源,對應着Action類中的某個屬性,類型為InputStream,,struts2會尋找一個返回類型為InputStream的方法getInputStream()(方法名最好為getInputStream,有人說此方法名可以為別的可能需要與struts.xml中的inputName保存一致下面有解釋,另一種理解:action中定義一個返回InputStream的方法,該方法作為被下載文件的入口,且需要配置stream類型結果時指定inputName參數,inputName參數的值就是方法去掉get前綴、首字母小寫的字符串。
下面則列出了和下載有關的一些參數列表: