[摘 要]:Java不依賴平臺的特點使得它受到了廣泛的關注,許多和java相關的優秀技術不斷出現,JSP(Java Server Page)就是其中之一。我們應用JSP能夠開發出動態的、高性能的、安全的跨平臺的網站。在網站中實現文件的上傳、下載的技術也非常普遍。
[關鍵詞]:OutoutStream(輸出流) InputStream(輸入流) JavaBeans response MIME(Multipurpose Internet Mail Extensions,多目的Internet郵件擴展)
引言
當今利用JSP語言制做網站的技術備受青睞。因此我們的畢業設計也就選擇了應用JSP開發了我們的“軟件開發小組輔助交流系統”。我在這里簡單地就文件下載以及如何統計下載次數談論一下自己的想法。
1 介紹一下Java中的InputStream(輸入流)和OutputStream(輸出流)
java.io包提供大流量的流類。Java的I/O流提供一條通道程序,可以使用這條通道把源中的數據傳送到目的地。我們把輸入流的指向稱作源,程序從指向源的輸入流中讀取源中的數據。而輸出流的指向是數據要去的一個目的地,程序通過向輸出流中寫入數據把信息傳送到目的地。請看下面的輸入流和輸出流工作示意圖:
2 闡述JSP中實現文件下載可以使用的幾種方法:
通過對JSP的學習和在此次畢業設計過程中的經驗,我發現在JSP中實現文件的下載可以使用下面的3種辦法。
2.1使用超級鏈接直接連接到文件的物理地址
利用這種辦法實現對文件的下載很簡單,我們可以從數據庫中讀出每一個文件的相關信息以列表的形式輸出到網頁上。然后我們可以選擇其中的一項信息做成超級鏈接直接連接到這個文件所在的物理地址。程序代碼如下:
其中(String)rs.getString(“file_name”)是我們要下載的文件的名字。而<%=filename%>就是輸出到網頁中的一個變量名,這里是文件名。就是它直接超級鏈接到這個物理文件所在的路徑(這里用的是相對路徑)。那么當我們點擊這個超級鏈接時便可以對該文件進行下載了。這種辦法很簡單,但是它存在一些缺陷,通常情況下當我們左鍵點擊該超級鏈接時就會直接打開該文件,因為我們訪問的是遠端的服務器上的文件,所以速度特別慢。還有,這種下載文件的方法我們不容易統計下載次數。所以,我們沒有采用這種辦法做文件下載。
2.2使用http://www.jspsmart.com網站提供的SmartUpload組件實現文件下載
這種方法也非常簡單,我們只要登陸這個站點下載這個SmartUpload組件,因為我們是利用JSP開發我們的系統,而且這個組件是一個編譯好的JavaBeans,所以我們必須把這個組件放在我們建好的web站點下的虛擬目錄下的WEB-INF文件夾下的classes文件夾下,然后我們只要用文本編輯器編寫以下幾行代碼就可以輕松實現文件下載。
<%@ page contentType=\"text/html;charset=gb2312\" import=\"com.jspsmart.upload.*\" %>
<%
// 新建一個SmartUpload對象
SmartUpload su = new SmartUpload();
// 初始化
su.initialize(pageContext);
// 設定contentDisposition為1以禁止瀏覽器自動打開文件,
//若不設定,擴展名為doc時,瀏覽器將自動用word打開它。
//若不設定,擴展名為pdf時,瀏覽器將用acrobat打開。
su.setContentDisposition(1);
// 下載文件
su.downloadFile(\"/upload/被下載的文件.doc\");
%>
我們利用這個JavaBeans組件可以很輕松地實現文件的上傳和下載。
2.3使用Java中的OutputStream(輸出流)對文件進行下載
JSP內置對象response調用方法getOutputStream()可以獲取一個指向客戶的輸出流,服務器將文件寫入這個流,客戶端就可以下載這個文件了。當JSP頁面提供下載功能時,應當使用response對象向客戶端發送HTTP頭信息,說明文件的MIME(Multipurpose Internet Mail Extensions,多目的Internet郵件擴展)類型,這樣客戶端的瀏覽器就會調用相應的外部程序打開下載的文件。例如,Ms-Word文件的MIME類型是application/msword, pdf文件的MIME類型是application/pdf。還有幾點特別要注意的是,執行下載的頁面,在JSP代碼范圍之外(即<% ... %>之外),不能包含任何HTML代碼、空格、回車或換行等字符,如果有的話將不能正確下載。因為它影響了返回給瀏覽器的數據流,導致解析出錯。我在一開始編寫下載這部分代碼時,就出現了這種錯誤。當我在瀏覽器里打開這個JSP頁就提示有這種OutputStream錯誤,后來我還是通過上網查找資料找到了問題的癥結所在,我把所有的HTML代碼都刪除,最后問題終于解決了。
例如下面的程序(loadfiles.jsp)就是用這種辦法實現文件下載的。
<%@ page contentType=\"text/html;charset=gb2312\" %>
<%@ page import=\"java.io.*\"%>
<%@ page import=\"java.sql.*\"%>
<%
/****** 特別注意:本程序之前不能有任何空格或換行符!! 整個JSP中不能使用任何html標記!! ******/
String name=\"\";
int newloadtimes=0;
String id=request.getParameter(\"fname\");
String sql1=\"select file_name,load_times from file where file_name='\"+id+\"'\";
ResultSet rs=conn.executeQuery(sql1);
if(rs.next())
{
name=rs.getString(\"file_name\");
newloadtimes = Integer.parseInt(rs.getString(\"load_times\"))+1;
}
//修改下載次數
out.print(id);
String sql2=\"update file set load_times=\"+newloadtimes+\" where file_name='\"+id+\"'\";
conn.executeUpdate(sql2);
OutputStream o = response.getOutputStream();
Byte[] temp = name.getBytes(\"ISO-8859-1\");
name = new String(temp,\"utf-8\");
String filedir=\"E:/system/FILES/\";
//提示客戶端保存還是打開文件的對話框如果取消下面這一句代碼客戶端瀏覽器將調用相應的外部程序,在當前位置直接打開文件
response.setHeader(\"Content-Disposition\", \"attachment;filename=\" + new String(name.getBytes(),\"ISO-8859-1\"));
response.setContentType(\"text/html;charset=utf-8\");
FileInputStream in = new FileInputStream(filedir+name);
int bytesRead;
//輸出文件用的字節數組,每次發送4k字節到輸出流
Byte[] buf = new byte[4 * 1024];
while ( (bytesRead = in.read(buf))!= -1)
{
o.write(buf, 0, bytesRead);
}
in.close();
o.close();
%>
我在此次畢業設計中就是應用這種方法實現文件下載的。我個人認為這種方法較前兩種方法比較合適。通過對這種方法的學習和應用,我理解了Java中InputStream(輸入流)和OutputStream(輸出流)這兩個類以及InputStream從源中讀取數據的方法和OutputStream向輸出流寫入數據的方法。
3 實現統計文件的下載次數
我們為了知道用戶對哪些文件感興趣,用戶經常頻繁地下載哪些文件,因此我們要統計文件的下載次數,這樣我們就可以了解用戶的需求,以便可以更好地為用戶服務。例如上面的代碼不但實現了文件的下載,而且還可以統計文件被下載的次數。上面的程序(loadfiles.jsp)里的以下幾行代碼就實現了統計文件下載的次數。
String name=\"\";//下載的文件的名字
int newloadtimes=0;//文件下載次數,初值為0
String id=request.getParameter(\"fname\");//上一頁傳過來的值(文件名)
//下面的SQL語句提取出下載的文件的文件名以及下載次數
String sql1=\"select file_name,load_times from file where file_name='\"+id+\"'\";
ResultSet rs=conn.executeQuery(sql1);//執行查詢
if(rs.next())
{
name=rs.getString(\"file_name\");
newloadtimes = Integer.parseInt(rs.getString(\"load_times\"))+1;//把下載次數加1
}
//修改下載次數
out.print(id);//輸出上一頁傳過來的文件名,進行測試
String sql2=\"update file set load_times=\"+newloadtimes+\" where file_name='\"+id+\"'\";
//更新表把新的下載次數寫入數據表
conn.executeUpdate(sql2);//執行更新
4總結
通過此次畢業設計的鍛煉,我掌握了怎樣實現文件的下載和如何統計下載次數的方法,同時我還學到了很多JSP的其它知識,基本上掌握了利用JSP開發網站的編程思想。領會到了JSP中最核心的內容之一--JavaBeans的優點。JavaBeans可以實現代碼的重復利用;易編寫、易維護、易使用;能夠運行在任何已經安裝了Java的平臺,而且不用重新編譯。例如我們開發這個“輔助交流系統”時訪問數據庫的各項操作就做成了一個JavaBeans。應用起來非常方便。
致謝:在此次畢業設計過程中和畢業論文的寫作過程中,馬季骕和蘇貴斌老師給予了精心的指導并且提出了寶貴的意見,為我提供了極大的幫助,在這里向二位老師表示衷心的感謝!
參考文獻:
[1]耿祥義、張躍平.《JSP使用教程》清華大學出版社2003年
[2]孫一林、彭波.《Java數據庫編程實例》清華大學出版社2003年
[3]林邦杰《JSP交互網站實務精典》北京中國青年出版社2001年