使用JSP對檔案下載的控制

來源:互聯網
上載者:User
js|控制|下載 出自孟憲會大大的blog
Web開發人員都有過這樣的疑問,如何讓一個檔案,尤其是一個已知類型的檔案,發送到用戶端,直接提示讓瀏覽者下載,而不是用與它相關聯的程式開啟。以前我們最常用的辦法就是把這樣的檔案加到連結上,這樣可以讓瀏覽者通過點擊滑鼠右鍵的目標另存新檔來下載所連結的檔案。但是,這樣有兩個不足的地方:
一是:如果瀏覽器能夠識別已下載檔案的副檔名,則瀏覽器就會啟用該副檔名所關聯的程式來開啟所下載的檔案。比如:在Windows平台上,如果使用者點擊的網站連結接的是一個“.doc”檔案的話,那麼,瀏覽器就會啟動Microsoft Word應用程式來開啟它。
二是:如果採用連結的辦法的話,任何能看到該連結的人都可以下載該檔案,你雖然也可以對所下載的檔案進行使用權限設定,但那樣做也不是很方便的。有時候我們需要更為靈活和富有彈性的方式,下面的程式能夠很方便地克服以上兩方面的不足。
這種辦法是可靠的,但你必須記住:沒有授權的使用者不能夠通過在瀏覽器地址欄裡輸入檔案的URL來取得該檔案的下載權。所以,要下載的檔案應該放到虛擬目錄之外的一個目錄裡,比如:如果你的虛擬目錄是C:\Mengxianhui\Tomcat4\Website\MyApp的話,那麼,存放在該目錄和該目錄下的任何子目錄下所有檔案對網際網路上的任何使用者都是可見的。要直接下載一個檔案,我們需要做兩件事,第一件事是:設定響應的內容類別為“application/octet-stream”,大小寫無關。第二件事是:設定HTTP的回應標頭名字為:Content-Disposition,設定值為:attachment; filename = theFileName。這裡的theFileName就是出現在檔案下載對話方塊裡的預設檔案名稱,通常和所下載的檔案名稱字相同,但也可以不同。下面,我們就平常最常用的JSP和ASP頁面來舉一個實際應用的例子。

TestFileDownload.JSP頁面的例子:

<%
// 得到檔案名稱字和路徑
String filename = "MengxianhuiDocTest.doc";
String filepath = "D:\\";

// 設定回應標頭和下載儲存的檔案名稱
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition",
"attachment; filename=\"" + filename + "\"");

// 開啟指定檔案的流資訊
java.io.FileInputStream fileInputStream =
new java.io.FileInputStream(filepath + filename);

// 寫出流資訊
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
out.close();
%>

值得注意的是:在你要下載的檔案內容裡,除了檔案的內容之外,不應該再附加有其它任何的字元,包括空格和斷行符號分行符號。我們有時在編寫代碼的時候,為了使代碼清晰可讀,往往會添加一些空格、定位字元或者斷行符號分行符號,這樣雖然看起來比較清晰,但有時可能會得不到正確的結果。比如:
<%@ page import="java.io.*"
%> <jsp:useBean id="MyBeanFromMengxianhui" scope="page"
class="com.Mengxianhui.DownloadBean" />
應該寫成這樣:
<%@ page import="java.io.*"
%><jsp:useBean id="MyBeanFromMengxianhui" scope="page"
class="com.Mengxianhui.DownloadBean" />

TestFileDownload.ASP頁面的例子:

在ASP裡,沒有提供從檔案讀取檔案流資訊的方法,因此,為了得到檔案的流資訊,我們必須藉助其他的工具,最簡單的就是編寫一個VB或C的DLL組件,讓組件返迴文件的流資訊。下面是一個用VB編寫的DLL的例子,工程名字為MengXHFileDownLoad,類別模組的名字為BinReadFromFile,類方法readBinFromFile如下:

Function readBinFromFile(ByVal bfilename As String) As Variant
Dim fl As Long
Dim FileNum As Long
Dim binbyte() As Byte
Dim binfilestr As String

On Error GoTo errHandler
FileNum = FreeFile
Open bfilename For Binary As #FileNum
fl = FileLen(bfilename)
ReDim binbyte(fl)
Get #FileNum, , binbyte
Close #FileNum
readBinFromFile = binbyte
Exit Function

errHandler:
Exit Function
End Function

把上面的代碼編譯成MengXHFileDownLoad.DLL,然後註冊即可使用。下面以直接下載一個When A Man Loves A Woman.mp3的MP3檔案為例子,我們要編寫的ASP指令碼代碼如下:

<%@ Language=VBScript %>
<%
Response.buffer = TRUE
Response.ContentType = "APPLICATION/OCTET-STREAM"
Response.AddHeader "Content-Disposition","attachment;filename=When A Man Loves A Woman.mp3"

Dim varStream, oMyObject

Set oMyObject = Server.CreateObject("MengXHFileDownLoad.BinReadFromFile")
varStream = oMyObject.readBinFromFile("E:\MengXianhui\Mp3\When A Man Loves A Woman.mp3")
Response.BinaryWrite(varStream)
Set oMyObject = Nothing

Response.End
%>

當我們運行上面的TestFileDownload.ASP檔案時,瀏覽器會彈出一個檔案下載的對話方塊,提示我們下載,而不是用預設的MP3播放器開啟。
這種方法也可以把我們的ASP頁面產生的HTML原始碼儲存成一個檔案,下面的代碼會提示你把ASP執行的結果儲存成Test.htm檔案。具體的方法是:
<%
Response.ContentType = "APPLICATION/OCTET-STREAM"
Response.AddHeader "Content-Disposition","attachment;filename=Test.htm"
Response.write "<div style='background-color:navy;color:#FFFFFF'>測試</div>"
Response.write "<a href='http://lucky.myrice.com'>"
Response.write "<img src='back.jpg'>【孟憲會之精彩世界】</a>"
Response.End
%>

當我們的檔案數目很少時,也可以直接在伺服器端進行設定,讓這些檔案直接下載。具體做法是:在Internet服務管理員裡,選“屬性”項,然後選“HTTP Headers”標籤頁進行設定即可!!




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.