理解和靈活應用 Struts2 的檔案下載功能

來源:互聯網
上載者:User

原文地址:http://www.blogjava.net/Unmi/archive/2009/06/17/282780.html


檔案下載給我們最直接的概念就是,給個檔案連結點擊就下載。似乎太簡單,然而 Struts2

卻把它作為一個獨立的學問來對待,理由有四:

1.
檔案名稱為中文時,直接點擊下載,連結可能會走樣(某些瀏覽器,URL 編碼的問題),致使無法下載。2.
不總是從下載實際的檔案,檔案內容有時候是動態產生的,如資料庫中的內容。
3.
對於知名的檔案類型不讓瀏覽器直接開啟,而是出現下載對話方塊儲存檔案。例如,要下載的檔案是 .txt 的,可能直接就在瀏覽器中顯示其內容。
4.
需要授權才能
下載
檔案

當然對於以上若干問題,Servlet/JSP 都能通過正確的 URL 編碼,回應標頭設定、許可權代碼控制解決,只是 Struts2
讓我們處理起來更方便了,內部原理自然是一樣的。

先來看下 Servlet 如何?檔案下載的,直接見代碼:

PrintWriter out = response.getWriter();<br />//不管實際類型,待下載檔案ContentType統一指定為 application/octet-stream<br />response.setContentType("application/octet-stream");<br />//中文檔案名稱必須轉碼為 ISO8859-1,否則為亂碼<br />String fileName = new String("文字檔.txt".getBytes(), "ISO8859-1");<br />//作為附件下載,相應的 "inline;filename = "+fileName 是線上(瀏覽器中顯示內容)開啟<br />response.setHeader("Content-Disposition", "attachment;filename=" + fileName);<br />//因為檔案編碼也為 ISO8859-1,所以內容須轉碼成 ISO8859-1,尚不知如何控制下載文字檔的編碼<br />//或有誰知道的,還請告訴我一下。 檔案內容可以從物理檔案中來,或者資料庫中讀取填入等等<br />out.write(new String("Servlet 檔案下載測試".getBytes(), "ISO8859-1"));<br />out.close();



 

知道了上面各行的含義,再來看下 Struts2
的解決方式,其實不過是把某些代碼的功能移入到了設定檔而已。在李剛所著的《Struts 2
權威指南》中說 Struts 實現檔案下載是由一個 download 攔截器。其實不然,只是一個
StreamResult(org.apache.struts2

.dispatcher.StreamResult)
而已,也不像實現檔案上傳那樣要額外的 JAR 包。在 StreamResult 中有以下幾個預設屬性要留意一下:

   
public static final String DEFAULT_PARAM = "inputName";
    protected String contentType = "text/plain";
    protected
String contentDisposition = "inline";
    protected String inputName =
"inputStream";
    protected InputStream inputStream;
   
protected int bufferSize = 1024;

StreamResult
的實現細節敬請閱讀它的原始碼,實現過程一言以蔽之就是:從 inputStream 擷取內容,以相應的
contentType、contentDisposition 和 bufferSize 輸出給瀏覽器,對 contentType 和
contentDisposition 的相應設定就能實現檔案下載,可對照前面 Servlet 的實現。看個實際的例子吧。

struts.xml
中 Action 的配置,假定 Action 類為 com.unmi.DownLoadAction

<action name="download" class="com.unmi.action.DownloadAction"><br /><result name="success" type="stream"><!--type 為 stream 應用 StreamResult 處理--><br /> <param name="contentType">application/octet-stream</param><!--預設為 text/plain--></p><p> <!-- 預設就是 inputStream,它將會指示 StreamResult 通過 inputName 屬性值的 getter 方法,<br /> 比如這裡就是 getInputStream() 來擷取下載檔案的內容,意味著你的 Action 要有這個方法 --><br /> <param name="inputName">inputStream</param></p><p> <!-- 預設為 inline(線上開啟),設定為 attachment 將會告訴瀏覽器下載該檔案,filename 指定下載文<br /> 件保有存時的檔案名稱,若未指定將會是以瀏覽的頁面名作為檔案名稱,如以 download.action 作為檔案名稱,<br /> 這裡使用的是動態檔案名稱,${fileName}, 它將通過 Action 的 getFileName() 獲得檔案名稱 --><br /> <param name="contentDisposition">attachment;filename="${fileName}"</param><br /> <param name="bufferSize">4096</param><!-- 輸出時緩衝區的大小 --><br /></result><br /></action>

 

 

說明:對於上面的配置其他參數可以用預設值,關鍵就是 contentDisposition 要設定為 attachment 才能提示下載,同時用
filename 指定檔案名稱,若直接指定非動態檔案名稱。

DownloadAction 代碼,需要實現
getInputStream() 返回輸入資料流;因前面用的動態檔案名稱,所以須加上 getFileName()
返迴文件名,若非動態檔案名稱,則該方法可省去。

package com.unmi.action;<br />import java.io.*;<br />import java.text.*;<br />import java.util.Date;<br />/**<br /> * 檔案下載的 Action<br /> * @author Unmi<br /> */<br />public class NetbookSerialAction {<br />public String execute() throws Exception {<br />//這裡可加入許可權控制<br />return "success";<br />}<br />//獲得下載檔案的內容,可以直接讀入一個物理檔案或從資料庫中擷取內容<br />public InputStream getInputStream() throws Exception {<br />//return new FileInputStream("somefile.rar"); 直接下載 somefile.rar<br />//和 Servlet 中不一樣,這裡我們不需對輸出的中文轉碼為 ISO8859-1<br />return new ByteArrayInputStream("Struts2 檔案下載測試".getBytes());<br />}<br />//對於配置中的 ${fileName}, 獲得下載儲存時的檔案名稱<br />public String getFileName() {<br />DateFormat df = new SimpleDateFormat("yyyy-MM-dd");<br />String fileName = "序號(" + df.format(new Date()) + ").txt";<br />try {<br />//中文檔案名稱也是需要轉碼為 ISO8859-1,否則亂碼<br />return new String(fileName.getBytes(), "ISO8859-1");<br />} catch (UnsupportedEncodingException e) {<br />return "impossible.txt";<br />}<br />}<br />}

 

謹記一個就是,要想下載的檔案名稱不亂碼就要以 ISO8859-1 字元集進行轉碼,內容會否亂碼可在調試中解決。

好啦,啟動服務,訪問


http://localhost:8080/teststruts2/download.action

瀏覽器便會提示下載 序號(2009-06-17).txt,內容為:“Struts2
檔案下載測試”。

參考:1.

談Struts2
下載檔案
的方法
實現

        2. struts2
多檔案動態下載及中文解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.