如何使用jsp设置进度条值

时间:2015-04-06 10:53:41

标签: java jsp servlets

我正在尝试制作一个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代码很长,因为每个字节都会打印一个脚本代码。

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

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

嗨首先我认为你应该把这个过程存储在会话中。然后使用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 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()方法并添加逻辑以增加进度。