數據導入與實時進度條實現

digiflow數據導入與實時進度條實現javascript

 

本文檔只是稍微解析下數據導入的流程,以及講解實時進度條實現方法html

 

數據批量導入流程java

1、客戶把.txt數據打包成.gz文件,發給咱們。緩存

GZ文件格式,每一個文件的第一行是惟一的數據,導入完成後要插入到ImportRecordtomcat

名字格式:DigiFlow_南寧 - 平安出單中心_20100201_000100ECHW8P8708.txt服務器

內容格式:以」||」爲分割符網絡

好比:00||000100ECHW8P8708||8||18:08:17session

00表明表名稱app

000100ECHW8P8708 表明這個文件的惟一標識jsp

 

2JAVA解壓縮GZ文件

JAVA提供了GZIPInputStream 解壓API,把裏面的內容寫入到txt文件裏。

 

3、解壓的文件臨時存放目錄

一種是在安裝的TOMCAT根目錄下新建file目錄,而後System.getProperty("user.dir") + "/file/"

二種是System.getProperty("java.io.tmpdir")獲得的是tomcat的臨時目錄

項目中用到的是第一種

 

4讀取解壓的文件

if("00".equals(fileinfos[0]))  讀取到第一行時,根據UID判斷是否導入過該文件。若是導入過則系統提示,並刪除解壓的文件。若是沒有導入過,則繼續執行下一步直到導入完成,完成後再插入這個文件的惟一標識。如:000100ECHW8P8708

 

讀取到其餘行時,獲取其UID,判斷是否插入過該記錄。若是插入過,則執行update。若是沒插入過,則執行insert.

 

5、拼SQL實現方式實現DMLinsertupdate

程序中的insertupdate語句是得到文件的中的列名以後,經過表名和列明去查找相應的字段信息,有的字段是varcharchardatetime型則加上‘’號。詳細參見源碼bossdataimportBusinessDAOImpl.java類的getStringType()方法。

 

 

 

 

AJAX實現實時WEB進度條

咱們爲了改善用戶界面,一般會在處理量大或者是網絡速度較慢的時候,給用戶顯示一個處理進度,讓用戶心理有底,加強用戶等待結果的耐心,以改善用戶體驗。爲了達到這個效果,一般作法有兩大類:簡單等待和真實的處理進度,本文着重討論第二種方法的實現。

 

1)簡單的等待界面:這種作法之因此說簡單,就是在用法發送了處理命令後,當即在頁面的某個地方替換一個waiting的圖片,好比一個轉圈的GIF,一張Loading的圖片等,這種不稱之爲進度條,頂多就是個等待條,但一般仍是能夠給用戶帶來那麼點知足,在業務量不大的狀況下,也夠用了,例子參見http://www.belitastone.com的首頁。

 

2)真實的等待進度:好比說,我要在B/S系統中實現一個數據導入的功能,數據文件總共有100個,每一個文件包含成千上萬的數據,導入過程可能須要15分鐘,那麼我還用一個圖片在那邊打轉嗎?如今這樣仍是不夠的,我可能須要讓使用者知道,我當前處理的是第幾個文件,還剩下幾個,處理的百分比,並顯示一個加載的真實進度條,這個進度條要如實反映處理的百分比。

 

實現1:因爲用戶處理的數據量大,能夠在文件導入過程當中,循環計算進度,並將進度信息存儲在上下文中,並在前臺頁面定時從上下文讀取進度數據,並在頁面顯示。這種方法思路比較直接。

 

實現2:使用觀察者模式,實現進度主動通知。思路是:在文件導入過程當中,計算進度信息,並將進度數據通知給觀察者,前臺頁面定時向觀察者諮詢進度,並將進度顯示到頁面中。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhengtanyun/archive/2009/07/06/4325528.aspx

 

 

我來講下個人實現方式

關於他說的「實現1」,說把進度信息存儲到上下文,這個貌似有問題,這個上下文是servlet上下文?據我所知,上下文做用域和Application做用域同樣大,進度條每一個用戶執行不一樣的導入操做,存到上下文作什麼,還不亂套?

 

個人實現方式和「實現2」有點像。思路是:在文件導入過程當中,循環計算進度信息,並將進度數據放入SESSION,前臺頁面經過AJAX定時調用,獲取進度,並將進度顯示到頁面中.

進度數據有:總的數據量、已導入數據量、已經上傳時間。

 

另一種狀況:當正在進行導入時,點擊了別的頁面,從而頁面上的進度條就沒有了,然後臺卻還在運行。有幾種方法,一是彈出模式對話框,在模式框裏面進行導入,可是這樣還有點麻煩。二是當用戶點擊了別的頁面再回到導入頁面時,又從新讀取SESSION中的進度信息。這須要在ACTION中設置一個全局變量來做爲是否正在執行導入操做的標記。

 

 

 

最終效果圖:(見附件) 

 效果圖

 

 

代碼實現參考源代碼manage中的DigimpAction.java以及dimpImport.jsp

核心代碼以下:

ACTION 部分代碼

Java代碼  收藏代碼

  1. <strong>//  讀取數據導入實時狀態  

  2.     public ActionForward doStatus(ActionMapping mapping, ActionForm form,  

  3.             HttpServletRequest request, HttpServletResponse response) throws Exception  

  4.     {  

  5.         // 設置該響應不在緩存中讀取  

  6.         response.addHeader("Expires""0");  

  7.         response.addHeader("Cache-Control",  

  8.                 "no-store, no-cache, must-revalidate");  

  9.         response.addHeader("Pragma""no-cache");  

  10.         response.setHeader("Cache-Control""no-cache");  

  11.         response.setCharacterEncoding("utf-8");            

  12.         response.setContentType("text/html; charset=utf-8");            

  13.         int totalSize = 0;// 總數據的條數  

  14.         int bytesRead = 0;// 已導入數據條數  

  15.         long getElapsedTimeInSeconds=0;// 得到已經上傳得時間  

  16.         HttpSession session = request.getSession(false);  

  17.         if (session.getAttribute("TOTALSIZE")  != null) {  

  18.             if(count == 0){  

  19.                 session.removeAttribute("TOTALSIZE");  

  20.             }else{  

  21.                 totalSize=Integer.parseInt(session.getAttribute("TOTALSIZE").toString());  

  22.                   

  23.             }  

  24.         }  

  25.         if (session.getAttribute("BYTESREAD")  != null) {  

  26.             if(count == 0){  

  27.                 session.removeAttribute("BYTESREAD");  

  28.             }else{  

  29.                 bytesRead=Integer.parseInt(session.getAttribute("BYTESREAD").toString());  

  30.             }  

  31.         }  

  32.         if (session.getAttribute("STARTTIME")  != null) {  

  33.             long stime=Long.parseLong((String)session.getAttribute("STARTTIME"));  

  34.             getElapsedTimeInSeconds=(System.currentTimeMillis() - stime) / 1000;  

  35.         }  

  36.           

  37.         //計算上傳完成的百分比  

  38.         String percentComplete="0";  

  39.         if(totalSize > 0){  

  40.             double k = (double)bytesRead/totalSize*100;   

  41.             BigDecimal big=new BigDecimal(k);    

  42.             percentComplete = big.setScale(2,BigDecimal.ROUND_HALF_UP).toString();   

  43.         }  

  44.         //得到上傳已用的時間  

  45.         long timeInSeconds = getElapsedTimeInSeconds;  

  46.         //計算平均上傳速率  

  47.         //double uploadRate = bytesRead / (timeInSeconds + 0.00001);  

  48.         //System.out.println("**************計算平均上傳速率="+bytesRead);  

  49.         // 計算總共所需時間  

  50.         //double estimatedRuntime = totalSize / (uploadRate + 0.00001);  

  51.           

  52.         //將上傳狀態返回給客戶端  

  53.         response.getWriter().println("<b>Import Status:</b><br/>");  

  54.         if (bytesRead != totalSize) {  

  55.             response.getWriter().println(  

  56.                     "<div class=\"prog-border\"><div class=\"prog-bar\" style=\"width: "  

  57.                             + percentComplete + "%;\"></div></div>");  

  58.             response.getWriter().println(  

  59.                     "Imported: " + bytesRead + " out of " + totalSize  

  60.                             + " Records (" + percentComplete + "%) <br/>");  

  61.             response.getWriter().println(  

  62.                     "Runtime: " + formatTime(timeInSeconds) + " <br/>");  

  63.         } else {  

  64.             response.getWriter().println(  

  65.                     "Imported: " + bytesRead + " out of " + totalSize  

  66.                             + " Records<br/>");  

  67.             response.getWriter().println("Complete.<br/>");  

  68.         }  

  69.         //若是文件已經導入完畢  

  70.         if (bytesRead == totalSize) {  

  71.             response.getWriter().println("<b>Imported complete.</b>");  

  72.         }  

  73.         return null;  

  74.     }  

  75.     private String formatTime(double timeInSeconds) {  

  76.         long seconds = (long) Math.floor(timeInSeconds);  

  77.         long minutes = (long) Math.floor(timeInSeconds / 60.0);  

  78.         long hours = (long) Math.floor(minutes / 60.0);  

  79.   

  80.         if (hours != 0) {  

  81.             return hours + "hours " + (minutes % 60) + "minutes "  

  82.                     + (seconds % 60) + "seconds";  

  83.         } else if (minutes % 60 != 0) {  

  84.             return (minutes % 60) + "minutes " + (seconds % 60) + "seconds";  

  85.         } else {  

  86.             return (seconds % 60) + " seconds";  

  87.         }  

  88.     }  

  89.     //頁面調用此方法,檢查導入工做是否正在進行時,0:無 1:正在進行  

  90.     public int checkImportStatus(){  

  91.         return count;  

  92.     }  

  93. </strong>  

 

 

 

 

dimpImport.jsp  部分代碼

Java代碼  收藏代碼

  1. <script type="text/javascript">  

  2.     var xmlHttp;   

  3.     function createXMLHttpRequest()//建立XMLHttpRequest對象   

  4.     {   

  5.         if(window.ActiveXObject){   

  6.             xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");   

  7.         }else if(window.XMLHttpRequest){   

  8.             xmlHttp = new XMLHttpRequest();   

  9.         }   

  10.     }   

  11.     //導入程序入口  

  12.     function tijiao(){  

  13.         document.forms[0].action=" ";  

  14.         document.forms[0].submit();  

  15.         go();  

  16.     }  

  17.     function go()   

  18.     {  

  19.         createXMLHttpRequest();//建立XMLHttpRequest對象  

  20.         xmlHttp.onreadystatechange = callBack;//設置回調函數   

  21.         var url = "digimp.do?method=doStatus";//請求的地址   

  22.         var button = document.getElementById("go");   

  23.         button.disabled = true;//設置按鈕不可用   

  24.         xmlHttp.open("post",url,true);//打開對服務器的鏈接   

  25.         xmlHttp.send();//發送請求   

  26.     }   

  27.     function callBack()   

  28.     {   

  29.         if(xmlHttp.readyState == 4){   

  30.             if(xmlHttp.status == 200){  

  31.                 setTimeout("go()",500);//定時調用  

  32.                 document.getElementById('status').innerHTML =xmlHttp.responseText;  

  33.             }   

  34.         }   

  35.     }  

  36.     //檢查是否有正在進行的導入操做  

  37.     function page_init(){  

  38.         DigimpAction.checkImportStatus(function callback_init(data){  

  39.             if(data != '0'){  

  40.                 document.getElementById("go").disabled = true;  

  41.                 go();  

  42.             }else{  

  43.                 document.getElementById("go").disabled = false;  

  44.             }  

  45.         });  

  46.     }  

  47.       

  48. </script>  

  49. <body onload="page_init();">  

  50.         <!-- 這裏顯示進度條 -->  

  51. <div id="status"></div>  

  52. </body>  

 

相關文章
相關標籤/搜索