最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java動態(tài)顯示文件上傳進度實現(xiàn)代碼

 更新時間:2022年06月23日 17:10:06   作者:fuzhouxufeng  
這篇文章主要為大家詳細介紹了Java動態(tài)顯示文件上傳進度實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例實現(xiàn)文件上傳的進度顯示,我們先看看都有哪些問題我們要解決。

1 上傳數(shù)據(jù)的處理進度跟蹤
2 進度數(shù)據(jù)在用戶頁面的顯示

就這么2個問題,
第一個問題,主要是組件的選擇
必須支持?jǐn)?shù)據(jù)處理偵聽或通知的組件。當(dāng)然,我肯定只用我自己的組件啦。基本原理是

1 使用request.getContentLength() 讀取到處理數(shù)據(jù)的總長度,注意這個長度不等于文件的長度,因為Base64等編碼會增加數(shù)據(jù)量,如果超過了允許的長度,直接返回-1;

2 在每讀取一部分?jǐn)?shù)據(jù)時(比如一行,或者64K,或者你自定義的字節(jié)數(shù)),將讀取的字節(jié)數(shù)通知我們的進度跟蹤程序。我取名為 UploadListener代碼如下

/*
* 處理附件上傳的通知。

* 各位可以繼承這個類,來實現(xiàn)自己的特殊處理。 
* 
* @author 趙學(xué)慶 www.java2000.net 
*/ 
 public class UploadListener ... { 
 // 調(diào)試模式將在控制臺打印出一些數(shù)據(jù) 
 private boolean debug;

 // 總數(shù)據(jù)字節(jié)數(shù) 
 private int total;

 // 當(dāng)前已經(jīng)處理的數(shù)據(jù)字節(jié)數(shù) 
 private int totalCurrent = 0 ;

 // 延遲,用來調(diào)試用,免得速度太快,根本卡看不到進度 
 private int delay = 0 ;

 /** */ /** 
 * 處理數(shù)據(jù)通知的方法。

 * 保存已經(jīng)處理的數(shù)據(jù)。并且在一定的比例進行延遲。默認每1%

 * 如果不需用延遲,可以刪掉內(nèi)部的代碼,加快速度。 
 * 
 * @param size 增加的字節(jié)數(shù) 
 */ 
 public void increaseTotalCurrent( long size) ... { 
 this .totalCurrent += size; 
 try ... { 
 currentRate = totalCurrent * 100 / total; 
  if (currentRate > lastRate) ... { 
  if (delay > 0 ) ... { 
  Thread.sleep(delay); 
  } 
  if (debug) ... { 
  System.out.println( " rate= " + totalCurrent + " / " + total + " / " + (totalCurrent * 100 / total)); 
  } 
  lastRate = currentRate; 
 } 
 } catch (Exception e) ... { 
 e.printStackTrace(); 
 } 
 } 

 /** */ /** 
 * 讀取全部自己數(shù) 
 * 
 * @return 
 */ 
 public int getTotal() ... { 
 return total; 
 } 

 /** */ /** 
 * 讀取已經(jīng)處理的字節(jié)數(shù) 
 * 
 * @return 
 */ 
 public int getTotalCurrent() ... { 
 return totalCurrent; 
 } 

 private long lastRate = 0 ;

 private long currentRate = 0 ;

 public int getDelay() ... { 
 return delay; 
 } 

 public void setDelay( int delay) ... { 
 this .delay = delay; 
 } 

 public void setTotal( int total) ... { 
 this .total = total; 
 } 

 public boolean isDebug() ... { 
 return debug; 
 } 

 public void setDebug( boolean debug) ... { 
 this .debug = debug; 
 } 
}

3 下面我們來看上傳的處理部分

 Upload upload = new Upload(request); 
 // 增加了偵聽進度的代碼 
 UploadListener uploadListener = new UploadListener(); 
 // 這句話我們后面再討論,這個可是關(guān)鍵 
 session.setAttribute( " uploadListener " ,uploadListener); 
 uploadListener.setDelay( 0 ); 
 uploadListener.setDebug( true ); 
 upload.setUploadListener(uploadListener); 
 upload.parse(); 
 // 這句話同樣重要,我們后面再討論 
 session.setAttribute( " uploadListener " , null );

4 我們再看上傳的表單部分

< script. type = " text/javascript. " > 
 function checkForm() ... { 
 $( " SHOW_FRAME. " ).src = " link.jsp " ; 
 $( ' SUBMIT ' ).disabled = true ; 
 Ext.MessageBox.show( ... { 
 title: ' Please wait... ' , 
 msg: ' Initializing... ' , 
 width: 240 , 
 progress: true , 
 closable: false 
 } ); 
 $( " MAIN_FORM. " ).submit(); 
 return false ; 
} 
 function setUploadProcess(total,current) ... { 
 var rate = Number(current) / Number(total); 
 Ext.MessageBox.updateProgress(rate, ' Uploading... ' + current + " / " + total); 
 if (Number(current) >= Number(total)) ... { 
 closeUploadProcess(); 
 } 
} 
 function closeUploadProcess() ... { 
 Ext.MessageBox.hide(); 
} 
</ script. > 
< iframe. name = " ACTION_FRAME. " id = " ACTION_FRAME. " width = " 0 " height = " 0 " ></ iframe. > 
< iframe. name = " SHOW_FRAME. " id = " SHOW_FRAME. " width = " 0 " height = " 0 " ></ iframe. > 
< form. method = " OST " id = " MAIN_FORM. " nsubmit = " return checkForm() " enctype = " multipart/form-data " 
 action = " uploadFileSave.jsp " target = " ACTION_FRAME. " > 
 < input type = " file " size = " 50 " name = " file " > 
 < input type = " submit " ID = " SUBMIT " value = " Upload It " > 
</ form. >

第一個iframe用于提交表單數(shù)據(jù),第二個就是我們用來獲取處理數(shù)據(jù)進度信息的。
提交表單很簡單,target指向了我們的第一個iframe.
我們看一下JS
checkForm. 里面第一句就是關(guān)鍵的讀取進度信息的頁面,我們在第二個iframe里面獲得。然后就是彈出進度的顯示框,我使用了Ext. 然后提交上傳表單
setUploadProcess 用來更新進度框上面的數(shù)據(jù),第一個參數(shù)是數(shù)據(jù)總共的大小,第二個參數(shù)是已經(jīng)處理的大小。
closeUploadProcess 關(guān)閉進度框

5 最后,我們來看讀取進度信息的頁面

<% @ page language = " java " contentType = " text/html; charset=utf-8 " pageEncoding = " utf-8 " %> 
<% @include file = " ../package.inc.jsp " %> 
<% 
 response.setHeader( " ragma " , " no-cache " ); 
 response.setHeader( " Cache-Control " , " no-cache " ); 
 response.setDateHeader( " Expires " , 0 ); 
 response.setBufferSize( 0 ); 
 UploadListener uploadListener = null ; 
 while (uploadListener == null || uploadListener.getTotalCurrent() <= 0 ) ... { 
 uploadListener = (UploadListener) session.getAttribute( " uploadListener " ); 
 out.print( " . " ); 
 out.flush(); 
 Thread.sleep( 10 ); 
 } 
 long total = uploadListener.getTotal(); 
 out.println(total); 
 long current; 
 out.flush(); 
 while ( true ) ... { 
 current = uploadListener.getTotalCurrent(); 
 if (current >= total) ... { 
 break ; 
 } 
 out.println( " <script. type='text/javascript'>parent.setUploadProcess(' " + total + " ',' " + current + " ');</script> " ); 
 out.flush(); 
 Thread.sleep( 10 ); 
 } 
%>< script. type = " text/javascript. " > parent.closeUploadProcess(); </ script. >

其中前面的循環(huán),用來判斷是否產(chǎn)生了上傳的信息,如果沒有則等待。

然后就是讀取上傳的信息,并計算后生成調(diào)用上級窗口的更新進度條的JS, 請注意out.print后面必須跟上out.flush,否則不會持續(xù)輸出到客戶端,也就不會看到連續(xù)的進度條變化。

總結(jié):

上面的部分比較亂,我這里總結(jié)一下關(guān)鍵點。

1、在上傳組件里面,把總大小和當(dāng)前讀取了的大小放到一個類里面,并持續(xù)更新,直到處理完畢
2、上傳的進度類,放在session里面,供進度讀取頁面讀取
3、進度讀取頁面,從session里面拿到數(shù)據(jù),并返回結(jié)果。

有幾個疑問解釋一下。

1、由于Http協(xié)議決定了,必須等request處理完畢才會返回輸出,所以不能在upload頁面里進行處理進度的顯示。我前面測試到1M左右的文件不成功,就是沒有考慮到這個問題。所以必須單獨用一個GET的程序進行讀取
2、讀取是一個持續(xù)不斷的過程,因為上傳大文件是很慢的!
3、如果你的應(yīng)用服務(wù)器啟用了GZIP壓縮,是容器管理的,那么很不幸,因為容易必須拿到所有的數(shù)據(jù),至少是一部分?jǐn)?shù)據(jù)才會返回,所以造成我們返回的那些很少的字節(jié)經(jīng)常會被截住,造成無法顯示上傳的連續(xù)過程。  

解決方法

1) 關(guān)閉GZIP, 我想許多人不會這么做 
2) 使用自定義的GZIP壓縮,判斷某些東西(比如URL),對他們不進行壓縮處理

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java文件重命名(文件批量重命名)實例程序代碼分享

    java文件重命名(文件批量重命名)實例程序代碼分享

    這篇文章主要介紹了java文件重命名的程序代碼,大家參考使用吧
    2013-12-12
  • 解決jmap命令打印JVM堆信息異常的問題

    解決jmap命令打印JVM堆信息異常的問題

    這篇文章主要介紹了解決jmap命令打印JVM堆信息異常的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 基于SpringBoot2的Shiro最簡配置操作(兩個文件)

    基于SpringBoot2的Shiro最簡配置操作(兩個文件)

    這篇文章主要介紹了基于SpringBoot2的Shiro最簡配置操作(兩個文件),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • SpringBoot動態(tài)定時任務(wù)實現(xiàn)完整版

    SpringBoot動態(tài)定時任務(wù)實現(xiàn)完整版

    最近有幸要開發(fā)個動態(tài)定時任務(wù),這里簡單再梳理一下,下面這篇文章主要給大家介紹了關(guān)于SpringBoot動態(tài)定時任務(wù)實現(xiàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • 基于SpringBoot和PostGIS的某國基地可視化實戰(zhàn)

    基于SpringBoot和PostGIS的某國基地可視化實戰(zhàn)

    本文以Java開發(fā)語言為例,使用SpringBoot框架來進行后臺開發(fā),詳細講解如何使用Leaflet對PostGIS的全球基地信息進行Web可視化,最后分享Web可視化結(jié)果,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • SpringBoot調(diào)用DeepSeek?API的完整操作指南

    SpringBoot調(diào)用DeepSeek?API的完整操作指南

    這篇文章主要為大家詳細介紹了SpringBoot調(diào)用DeepSeek?API的完整操作指南,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • SparkSQL使用快速入門

    SparkSQL使用快速入門

    spark SQL是spark的一個模塊,主要用于進行結(jié)構(gòu)化數(shù)據(jù)的處理。它提供的最核心的編程抽象就是DataFrame。這篇文章主要介紹了SparkSQL使用快速入門,需要的朋友可以參考下
    2021-08-08
  • MyBatis 自帶連接池的具體實現(xiàn)

    MyBatis 自帶連接池的具體實現(xiàn)

    MyBatis自帶的PooledDataSource實現(xiàn)了一個簡單的數(shù)據(jù)庫連接池,適合簡單場景,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • Java定時器例子_動力節(jié)點Java學(xué)院整理

    Java定時器例子_動力節(jié)點Java學(xué)院整理

    本文給大家分享了java定時器例子,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-05-05
  • springboot如何將http轉(zhuǎn)https

    springboot如何將http轉(zhuǎn)https

    這篇文章主要介紹了springboot如何將http轉(zhuǎn)https,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04

最新評論

达尔| 信丰县| 二连浩特市| 岳普湖县| 皮山县| 漠河县| 武胜县| 安庆市| 汾西县| 荥阳市| 曲沃县| 恩平市| 松阳县| 泽库县| 南阳市| 三原县| 肥东县| 合肥市| 德兴市| 日喀则市| 肥城市| 扎鲁特旗| 德格县| 江源县| 南丰县| 阿克陶县| 承德县| 宜阳县| 阜城县| 鹿邑县| 馆陶县| 遵义县| 长泰县| 巨野县| 元江| 灵宝市| 蓝田县| 韩城市| 合山市| 丰原市| 双江|