Struts2的框架提供了現成的文件下載方式,大大簡化了開發下載功能的便利性。網上的例子有很多,我把一些大家普遍比較關注的點,集中一下,給出一個整體方案。
一般我們照着書本或者網上的列子寫出了一個Demo,都會存在幾個疑問:
1.下載文件的文件名怎么搞?不搞的話瀏覽器默認名字是提交的action的名字,顯然不好
2.文件名里面想搞中文,但是實際上下載文件名出現了亂碼或不顯示中文怎么搞?
3.文件的擴展名怎么搞?比如要下載的文件是word(doc,docx)或者excel(xls,xlsx)怎么辦?難道讓用戶自己改擴展名,太不友好了吧。
下面我們逐個說明。
場景:我們需要下載存放在服務器tomcat中webapp文件夾,對應x項目根目錄下“電子表格.xlsx"文件。即tomcat\webapp\x\電子表格.xlsx文件。
並且希望用戶下載的名字是“我的電子表格.xlsx”。
首先,如同Struts2框架處理其他問題一樣,我們需要有一個標准的action類來對下載請求進行處理。
Action類:
Struts.xml的action配置
看完代碼后的解釋:
1.核心的下載功能是怎么實現的
第一,action類里面提供了InputStream流的對象is,並且在配置文件中,同Struts框架的inputName參數進行了綁定。Strut2利用Servlet本來就有的標准流服務提供給客戶端的瀏覽器進行下載。
關鍵配置:
result的type不再是一般的"dispatcher",而是"stream",表明返回給客戶端的是流對象。一個名字為"inputName"的param參數表示,你得告訴框架,
action類里面哪個參數是要提供下載的InputStream對象。我們這里就是is
關鍵代碼:
InputStream對象 is,並且必須有對應的get方法,不然框架拿不到這個對象。注意大小寫
為is對象賦值,得到真正文件的流對象。
2.名字怎么搞?
這種姿勢搞(順便把擴展名和中午字符一並搞了):
關鍵配置:
attachment標示告訴瀏覽器是附件,不要打開(有時候下載的文件是txt之類的有些瀏覽器默認自動打開,而不是下載)。
filename=&{fileName},指定要下載的文件是什么名字。${fileName}這個通配符加大括號表示,文件的名字不是fileName,而是在
action類中一個名字叫fileName的參數的值
關鍵編碼:
由於瀏覽器在只能識別用ISO8859-1編碼的UTF-8的字符串,所以我們需要在代碼中把中文的文件名用ISO8859-1再重新編碼一下。這樣就解決了中文問題。
擴展名怎么解決?看上面的圖,xlsx擴展名一並同文件名統一處理。下載的文件自然就帶這個擴展名了。
以上,文章開頭的三個問題得到解決。
至於buffersize就不解釋了,所有的流傳輸肯定都有緩沖的概念。
有人可能會問,為什么action的配置中,param參數了沒有如<param name="contentType">application/zip</param>這樣的配置。其實這就是html頁面的頭部標記。
我不用是因為:
我不需要呀!因為result的type設置為stream,讓瀏覽器已經知道了是流文件,再加上contentDisposition把文件名連同連擴展名都搞定了,加上這個頭參數沒啥用。不信可以加上,隨便設置什么MIME的頭標記,都不起作用了。
當然,如果每次下載的都是固定名字,配置文件也可以這樣:
這串文字代表MIME協議(多用途的網際郵件擴充協議;)里面的xlsx格式。
下面附上MIME常用的數據類型對應關系:
.doc application/msword
以上