如何使用 jsp 设置进度条值

How to set progress bar value using jsp

我正在尝试制作一个 servlet 来在线下载文件。为此,我在jsp.

中做了一个进度条元素
<progress id="p1" max="100" value="0"><span>0</span>%</progress>

和java更新进度值的脚本代码:

function setProgress(value)
{
var progressBar = document.getElementById("p1");
progressBar.value = value;
progressBar.getElementsByTagName('span')[0].textContent = value;
}

现在,在servlet代码中更改进度:

InputStream is = ..........;
byte[] bytes = new byte[size*1024];
int read = in.read();
for(int j=0;read!=-1;j++)
{
   bytes[j] = (byte)read;
   setProgress((int)getProgressDownload(bytes.length));
   read = in.read();
}

public float getProgressDownload(int dsize)
{
    return ((float)dsize/tsize)*100;//tsize is total file's size;
}
public void setProgress(int value)
{
    try
    {
       response.getWriter().write("<script>");
       response.getWriter().write("setProgress(\"p1\","+value+");");
       response.getWriter().write("</script>");
    }
    catch(Exception e)
    {
       e.printStackTrace();
    }
}

现在的问题是 HTML 代码变长了,因为它会为每个字节打印一个脚本代码。

我应该怎么做才能防止这种情况发生?

感谢帮助

您好,首先我认为您应该将进程存储在会话中。然后使用 ajax 调用,您可以使用从某个 servlet 下面收到的响应定期更新进度条。添加映射和所有我只是在写 doGet 的东西.. 我还假设 URL 映射为这个特定 servlet 的 'progressServlet'.. 下面是 doGet 方法

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String downloadId = "longProcess_" + request.getParameter("downloadId");
        LongProcess longProcess = (LongProcess) request.getSession().getAttribute(downloadId);
        int progress = longProcess.getProgress();

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(String.valueOf(progress));
    }

然后在 JS 中,您可以使用 setTimeout() /setInterval() 以特定时间间隔调用下面给出的 checkProgress 方法,并在收到的进度 100% 完成时停止调用。您可以使用它来重复触发 Ajax 请求以请求进度的当前状态。

var refreshprogessbar = setInterval(checkProgress, 10000);// 10 seconds
function checkProgress() {/*pass the actual id instead of 12345*/
    $.getJSON('progressServlet?downloadId=12345', function(progress) {
        if(progress == 100){clearInterval(refreshprogessbar);}
        setProgress(progress);
    });
}

LongProcess 基本上是 class 用来跟踪正在进行的进程。以下是其中之一的示例:

class LongProcess extends Thread {
    private int progress;
    public void run() {
        while (progress < 100) {
            try { sleep(1000); } catch (InterruptedException ignore) {}
            progress++;
        }
    }    
    public int getProgress() {
        return progress;
    }
}

我只是递增进度归档成员,但您可以使用 setProgress() 方法并添加逻辑来增加进度。