熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

JSP編程進度條設計實例

2013-11-15 11:54:43  來源: JSP教程 

    許多Web應用企業應用涉及到長時間的操作例如復雜的數據庫查詢或繁重的XML處理等雖然這些任務主要由數據庫系統或中間件完成但任務執行的結果仍舊要借助JSP才能發送給用戶本文介紹了一種通過改進前端表現層來改善用戶感覺減輕服務器負載的辦法

    當JSP調用一個必須長時間運行的操作且該操作的結果不能(在服務器端)緩沖用戶每次請求該頁面時都必須長時間等待很多時候用戶會失去耐心接著嘗試點擊浏覽器的刷新按鈕最終失望地離開

    本文介紹的技術是把繁重的計算任務分離開來由一個獨立的線程運行從而解決上述問題當用戶調用JSP頁面時JSP頁面會立即返回並提示用戶任務已經啟動且正在執行JSP頁面自動刷新自己報告在獨立線程中運行的繁重計算任務的當前進度直至任務完成

    一模擬任務

     首先我們設計一個TaskBean類它實現javalangRunnable接口其run()方法在一個由JSP頁面(startjsp)啟 動的獨立線程中運行終止run()方法執行由另一個JSP頁面stopjsp負責TaskBean類還實現了 javaioSerializable接口這樣JSP頁面就可以將它作為JavaBean調用

    packagetestbarBean;

    importjavaioSerializable;

    publicclassTaskBeanimplementsRunnableSerializable{

    privateintcounter;

    privateintsum;

    privatebooleanstarted;

    privatebooleanrunning;

    privateintsleep;

    publicTaskBean(){

    counter=;

    sum=;

    started=false;

    running=false;

    sleep=;

    }

    }

    TaskBean包含的"繁重任務"是計算 ++…+的值不過它不通過*(+)/=公式計算而是由run()方法調用work()方法次完成計算 work()方法的代碼如下所示其中調用Threadsleep()是為了確保任務總耗時約

    protectedvoidwork(){

    try{

    Threadsleep(sleep);

    counter++;

    sum+=counter;

    }catch(InterruptedExceptione){

    setRunning(false);

    }

    }

    statusjsp頁面通過調用下面的getPercent()方法獲得任務的完成狀況

    publicsynchronizedintgetPercent(){

    returncounter;

    }

    如果任務已經啟動isStarted()方法將返回true

    publicsynchronizedbooleanisStarted(){

    returnstarted;

    }

    如果任務已經完成isCompleted()方法將返回true

    publicsynchronizedbooleanisCompleted(){

    returncounter==;

    }

    如果任務正在運行isRunning()方法將返回true

    publicsynchronizedbooleanisRunning(){

    returnrunning;

    }

    SetRunning()方法由startjsp或stopjsp調用當running參數是true時SetRunning()方法還要將任務標記為"已經啟動"調用setRunning(false)表示要求run()方法停止執行

    publicsynchronizedvoidsetRunning(booleanrunning){

    thisrunning=running;

    if(running)

    started=true;

    }

    任務執行完畢後調用getResult()方法返回計算結果如果任務尚未執行完畢它返回null

    publicsynchronizedObjectgetResult(){

    if(isCompleted())

    returnnewInteger(sum);

    else

    returnnull;

    }

     當running標記為truecompleted標記為false時run()方法調用work()在實際應用中run()方法也許要執行復 雜的SQL查詢解析大型XML文檔或者調用消耗大量CPU時間的EJB方法注意"繁重的任務"可能要在遠程服務器上執行報告結果的JSP頁面有兩 種選擇或者等待任務結束或者使用一個進度條

    publicvoidrun(){

    try{

    setRunning(true);

    while(isRunning()&&!isCompleted())

    work();

    }finally{

    setRunning(false);

    }

    }

    二啟動任務

    startjsp是webxml部署描述符中聲明的歡迎頁面webxml的內容是

    <?xmlversion=""encoding="GB"?>

    <!DOCTYPEwebapp

    PUBLIC"//SunMicrosystemsInc//DTDWebApplication//EN"

    "

    <webapp>

    <welcomefilelist>

    <welcomefile>startjsp</welcomefile>

    </welcomefilelist>

    </webapp>

    startjsp啟>動一個專用的線程來運行"繁重的任務"然後把HTTP請求傳遞給statusjsp

     startjsp頁面利用<jsp:useBean>標記創建一個TaskBean的實例將scope屬性定義為session使得對於來自 同一浏覽器的HTTP請求其他頁面也能提取到同一個Bean對象startjsp通過調用 sessionremoveAttribute("task")確保<jsp:useBean>創建了一個新的Bean對象而不是提取一個舊對 象(例如同一個用戶會話中更早的JSP頁面所創建的Bean對象)

    下面是startjsp頁面的代碼清單

    <%sessionremoveAttribute("task");%>

    <jsp:useBeanid="task"scope="session"

    class="testbarBeanTaskBean"/>

    <%tasksetRunning(true);%>

    <%newThread(task)start();%>

    <jsp:forwardpage="statusjsp"/>

    startjsp創建並設置好TaskBean對象之後接著創建一個Thread並將Bean對象作為一個Runnable實例傳入調用start()方法時新創建的線程將執行TaskBean對象的run()方法

     現在有兩個線程在並發執行執行JSP頁面的線程(稱之為"JSP線程")由JSP頁面創建的線程(稱之為"任務線程")接下 來startjsp利用調用statusjspstatusjsp顯示出進度條以及任務的執行情況注意statusjsp和 startjsp在同一個JSP線程中運行
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19871.html

    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.