首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP 進度條設計實作:長時間任務非同步執行與前端輪詢

     編輯:關於JSP

核心架構

  • TaskBean:實作 Runnable、Serializable,封裝長時間任務(模擬 1~100 累加,每步 100ms,共 10 秒)。
  • start.jsp:建立 TaskBean 存入 Session,啟動新執行緒執行 run(),轉發至 status.jsp。
  • status.jsp:輪詢 TaskBean.getPercent() 顯示進度條,任務完成則顯示結果。
  • stop.jsp:呼叫 setRunning(false) 中斷任務。

TaskBean 關鍵代碼

public class TaskBean implements Runnable, Serializable {
    private int counter = 0, sum = 0;
    private boolean started = false, running = false;
    private int sleep = 100;

    public synchronized void setRunning(boolean running) {
        this.running = running;
        if (running) started = true;
    }
    public synchronized int getPercent() { return counter; }
    public synchronized boolean isCompleted() { return counter == 100; }
    public synchronized Object getResult() {
        return isCompleted() ? new Integer(sum) : null;
    }
    protected void work() {
        try { Thread.sleep(sleep); counter++; sum += counter; }
        catch (InterruptedException e) { setRunning(false); }
    }
    public void run() {
        try { setRunning(true); while (isRunning() && !isCompleted()) work(); }
        finally { setRunning(false); }
    }
    // getter/setter 略
}

JSP 頁面流程

start.jsp

<% session.removeAttribute("task"); %>
<jsp:useBean id="task" scope="session" class="test.barBean.TaskBean"/>
<% task.setRunning(true); new Thread(task).start(); %>
<jsp:forward page="status.jsp"/>

status.jsp(自動刷新)

<jsp:useBean id="task" scope="session" class="test.barBean.TaskBean"/>
<html><head>
    <meta http-equiv="refresh" content="1"> <!-- 每秒刷新 -->
    <title>任務進度</title>
</head><body>
    <% if (!task.isStarted()) { %>
        任務尚未啟動...
    <% } else if (task.isRunning()) { %>
        進度: <%= task.getPercent() %>% <br>
        <div style="width:300px;border:1px solid #000">
            <div style="width:<%=task.getPercent()%>%;background:#090;height:20px"></div>
        </div>
    <% } else if (task.isCompleted()) { %>
        完成! 結果 = <%= task.getResult() %>
    <% } %>
</body></html>

關鍵設計重點

  • Session 共享 Bean:scope="session" 確保同一用戶多請求存取同一任務實例。
  • 執行緒安全:所有狀態方法加 synchronized,避免 JSP 執行緒與任務執行緒競態。
  • 立即回應:start.jsp 瞬間返回,使用者無感等待,體驗大幅提升。
  • 輪詢頻率:meta refresh="1" 或 AJAX 定時請求,視任務長短調整。

實務延伸

  • 真實場景:複雜報表產生、大量資料匯入、影片轉碼、郵件群發。
  • 生產環境建議:使用 ExecutorService 管理執行緒池、引入 Future 追蹤、採用 WebSocket/Server-Sent Events 取代輪詢、任務狀態持久化至資料庫支援叢集。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved