1.概述
在實際的Web應該開發或網站開發過程中,經常需要實現檔案上傳的功能。在檔案上傳過程中,經常需要使用者進行長時間的等待,為了讓使用者及時瞭解上傳進度,可以在上傳檔案的同時,顯示檔案的上傳進度條。運行本執行個體,如圖1所示,訪問檔案上傳頁面,單擊“瀏覽”按鈕選擇要上傳的檔案,注意檔案不能超過50MB,否則系統將給出錯誤提示。選擇完要上傳的檔案後,單擊“提交”按鈕,將會上傳檔案並顯示上傳進度。
2.技術要點
主要是應用開源的Common-FileUpload組件來實現分段檔案上傳,從而實現在上傳過程中,不斷擷取上傳進度。下面對Common-FileUpload組件進行詳細介紹。
Common-FileUpload組件時Apache組織下的jakarta-commons項目下的一個子項目,該組件可以方便地將multipart/form-data類型請求中的各種表單域解析出來。該組件需要另一個名為Common-IO的組件的支援。這兩個組件包檔案可以到http://commons.apache.org網站上進行下載。
(1)建立上傳對象
在應該Common-FileUpload組件實現檔案上傳時,需要建立一個工廠對象,並根據該工廠對象建立一個新的檔案上傳對象,具體代碼如下:
DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);
(2)解析上傳請求
建立一個檔案上傳對象後,就可以應用該對象來解析上傳請求,擷取全部的表單項,可以通過檔案上傳對象的parseRequest()方法來實現。parseRequest()方法的文法結構如下:
public List parseRequest(HttpServletRequest request) throws FileUploadException
(3)FileItem類
在Common-FileUpload組件中,無論是檔案域還是普通表單域,都當成FileItem對象來處理。如果該對象的isFormField()方法傳回值為true,則表示是一個普通表單域,否則為一個檔案域。在實現檔案上傳時,可以通過FileItem類的getName()方法獲得上傳檔案的檔案名稱,通過getSize()方法獲得上傳檔案的大小。
3.具體實現
(1)建立request.js檔案,在該檔案中編寫Ajax要求方法。
(2)建立檔案上傳頁index.jsp,在該頁中添加用於獲得上傳檔案資訊的表單以及表單元素,並添加用於顯示進度條的<div>標籤和顯示百分比的<span>標籤,關鍵代碼如下:
<form enctype="multipart/form-data" method="post" action="UpLoad?action=uploadFile">
請選擇上傳的檔案:<input name="file" type="file" size="34">
註:檔案大小請控制在50M以內。
<div id="progressBar" class="prog_border" align="left"><img src="images/progressBar.gif" width="0" height="13" id="imgProgress"></div><span id="progressPercent" style="width:40px;display:none">0%</span><input name="Submit" type="button" value="提交" onClick="deal(this.form)"><input name="Reset" type="reset" class="btn_grey" value="重設"></td></form>
(3)建立上傳檔案的Servlet實作類別UpLpad。在該類中編寫實現檔案上傳的方法uploadFile(),在該方法中通過Common-FileUpload組件實現分段上傳檔案,並計算上傳百分比,即時儲存到Session中,關鍵代碼如下:
public void uploadFile(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=GBK");request.setCharacterEncoding("GBK");HttpSession session=request.getSession();session.setAttribute("progressBar",0); //定義指定上傳進度的Session變數String error = "";int maxSize=50*1024*1024; //單個上傳檔案大小的上限DiskFileItemFactory factory = new DiskFileItemFactory(); //建立工廠對象ServletFileUpload upload = new ServletFileUpload(factory); //建立一個新的檔案上傳對象try {List items = upload.parseRequest(request); // 解析上傳請求Iterator itr = items.iterator(); // 枚舉方法while (itr.hasNext()) {FileItem item = (FileItem) itr.next(); //擷取FileItem對象if (!item.isFormField()) { // 判斷是否為檔案域if (item.getName() != null && !item.getName().equals("")) {//是否選擇了檔案long upFileSize=item.getSize(); //上傳檔案的大小String fileName=item.getName(); //擷取檔案名稱if(upFileSize>maxSize){error="您上傳的檔案太大,請選擇不超過50M的檔案";break;}// 此時檔案暫存在伺服器的記憶體中File tempFile = new File(fileName); //構造檔案目錄臨時對象String uploadPath = this.getServletContext().getRealPath("/upload");File file = new File(uploadPath,tempFile.getName()); InputStream is=item.getInputStream();int buffer=1024; //定義緩衝區的大小int length=0;byte[] b=new byte[buffer];double percent=0;FileOutputStream fos=new FileOutputStream(file);while((length=is.read(b))!=-1){percent+=length/(double)upFileSize*100D; //計算上傳檔案的百分比fos.write(b,0,length); //向檔案輸出資料流寫讀取的資料session.setAttribute("progressBar",Math.round(percent)); }fos.close();Thread.sleep(1000); //線程休眠1秒} else {error="沒有選擇上傳檔案!";}}}} catch (Exception e) {e.printStackTrace();error = "上傳檔案出現錯誤:" + e.getMessage();}if (!"".equals(error)) {request.setAttribute("error", error);request.getRequestDispatcher("error.jsp").forward(request, response);}else {request.setAttribute("result", "檔案上傳成功!");request.getRequestDispatcher("upFile_deal.jsp").forward(request, response);}}
(4)在檔案上傳頁index.jsp中,匯入編寫的Ajax要求方法的request.js檔案,並編寫擷取上傳進度的Ajax要求方法和Ajax回呼函數,關鍵代碼如下:
<script language="javascript" src="js/request.js"></script><script language="javascript">var request = false;function getProgress(){ var url="showProgress.jsp"; //伺服器位址var param ="nocache="+new Date().getTime(); //每次請求URL參數都不同 ,避免上傳時進度條不動request=httpRequest("post",url,true,callbackFunc,param); //調用要求方法 }//Ajax回呼函數function callbackFunc(){if( request.readyState==4 ){ //判斷響應是否完成 if( request.status == 200 ){ //判斷響應是否成功var h = request.responseText; //獲得返回的響應資料,該資料位元上傳進度百分比h=h.replace(/\s/g,""); //去除字串中的Unicode空白符document.getElementById("progressPercent").style.display=""; //顯示百分比 progressPercent.innerHTML=h+"%"; //顯示完成的百分比document.getElementById("progressBar").style.display="block"; //顯示進度條document.getElementById("imgProgress").width=h*(235/100); //顯示完成的進度}}}</script>
(5)編寫showProgress.jsp頁面,在該頁中應用EL運算式輸出儲存在session域中的上傳進度條的值,具體代碼如下:
<%@page contentType="text/html" pageEncoding="GBK"%>${progressBar}
(6)編寫表單提交按鈕onclick事件所調用的JavaScript方法,在該方法通過window對象的setInterval()方法每隔一定時間請求一次伺服器,獲得最新的上傳進度,關鍵代碼如下:
function deal(form){form.submit(); //提交表單timer=window.setInterval("getProgress()",500); //每隔500毫秒擷取一次上傳進度}
以上所述是小編給大家介紹的基於Ajax技術實現檔案上傳帶進度條的相關知識,希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對雲棲社區網站的支援!