Java Web - Make a simple Wait ProgressBar By Server Response Data

一般在進行網頁操作的時候,某些功能會需要等待Server的處理,如匯入、匯出資料等,當下

有可能會因為資料過多,導致需要處理一段時間,因此有必要去呈現目前的處理進度,以此

使用者才可能知道還需要等多久及網頁有正常在運作。

在這邊將實作一個簡單的等待處理Bar,原理很單純,當使用者點擊按鈕的當下,Server端將

分成兩個處理程序,一個為獨立的執行緒,表示資料處理;而另一頭將製作一個迴圈來等待

,每兩秒跳出迴圈回傳目前Server資料處理的進度,在回傳的資料中會包含是否已處理完畢

及目前的處理的數量,以此更新前端Ext MessageBox的訊息!

接著,再次send request to server side 進行迴圈檢查處理狀態!  因此,以這個例子而言,將會一

直在send request 及 response text,算是一個很陽春、有點愚蠢的方式,有待更好的方法來改

善orz

PS. 若在兩秒的等待中,資料已處理完畢會提前跳出迴圈!

Client: ExtJS

在這邊前端的MessageBox乃是利用JavaScript程式庫來呈現,相關code如下:

  1. var start = "";
  2. function execProcess(){
  3. if(start == ""){
  4. Ext.MessageBox.show({
  5. title:"訊息",
  6. msg:"處理中...",
  7. progress:true,
  8. width:300,
  9. closable:true
  10. });
  11. }
  12. Ext.Ajax.request({
  13. url:'<%=request.getContextPath()%>/ProgressServlet',
  14. params:{isStart: start},
  15. method: 'POST',
  16. success: function ( result, request ) {
  17. var action = Ext.decode(result.responseText);
  18. var msg = action.result.info;
  19. var msg_sp = msg.split(":");
  20. start = msg_sp[1];
  21. p = parseInt(msg_sp[0])/30;
  22. var progress_msg = Math.round(100*p)+"% completed";
  23. if(action.result.success){
  24. Ext.MessageBox.updateProgress(p, progress_msg, "處理完畢!");
  25. setTimeout("Ext.MessageBox.hide()",2000);
  26. }else{
  27. Ext.MessageBox.updateProgress(p, progress_msg, "處理中...");
  28. execProcess();
  29. }
  30. },
  31. failure: function ( result, request) {
  32. var action = result.responseText;
  33. Ext.MessageBox.alert('Failed', action.result.info||'');
  34. }
  35. });
  36. }

劇情為按下按鈕後,首先利用全域變數start來判斷MessageBox的初始化,再來向Server端

送出請求,當得到回應後,由回應的JSON CODE來判斷是否已處理完畢,若否則再呼叫自

己重新送出請求!

PS. 在此已將處理的資料總數設為hard code

Server : Java

後端程式碼部分,如下:

  1. MyThread t = null;
  2. ...
  3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
  4. JSONObject response_text = new JSONObject();
  5. JSONObject response_info = new JSONObject();
  6. String isStart = request.getParameter("isStart");
  7. int waitSec = 0;
  8. if(isStart.equals("")){
  9. t = new MyThread();
  10. t.start();
  11. isStart = "N";
  12. }
  13. System.out.println("Enter wait.....");
  14. try {
  15. while(!t.isEnd()){
  16. try{
  17. Thread.sleep(1000);
  18. waitSec++;
  19. if(waitSec == 2)break;
  20. } catch(Exception e){
  21. e.printStackTrace();
  22. }
  23. }
  24. System.out.println("Leave wait.....");
  25. response_info.put("info", t.getCount()+":"+isStart);
  26. response_info.put("success", t.isEnd());
  27. response_text.put("result", response_info);
  28. } catch (JSONException e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. }
  32. response.getWriter().print(response_text.toString());
  33. }

首先,當得到client傳過來的參數來進行Thread的初始化,並執行資料處理,因此在下一次的

request時,就不會再進行這一段code。接著,進行等待的部分,檢查目前資料的處理狀態,

當設定的等待時間已過,則回傳相關資料給client,進行處理進度資料的更新!

MyThread部分
  1. class MyThread extends Thread{
  2. private int count;
  3. private boolean isEnd;
  4. public boolean isEnd() {
  5. return isEnd;
  6. }
  7. public void setEnd(boolean isEnd) {
  8. this.isEnd = isEnd;
  9. }
  10. public int getCount() {
  11. return count;
  12. }
  13. public void setCount(int count) {
  14. this.count = count;
  15. }
  16. public void run(){
  17. try{
  18. while(true){
  19. count++;
  20. System.out.println("Execute process is:"+count);
  21. Thread.sleep(1000);
  22. if(count == 30){
  23. isEnd = true;
  24. break;
  25. }
  26. }
  27. } catch(Exception e){
  28. e.printStackTrace();
  29. }
  30. }
  31. }

在這邊,資料的需要處理的數量是寫死的,若是碰到真實的例子就需要做一些修改囉!

DEMO





總結:

這個例子純粹只是測試用,其方法應該算是最直覺的方式,並沒有什麼可取之處,若有更好

的處理方式請不吝指教囉!

留言