In a recent project, there was an upload function: upload a CVS file, then parse the file and write it into the database. Since large files often need to be uploaded, it often takes 40 minutes for customers to complete this function. During this process, the page also There is no prompt and the user experience is very bad?
Why not use ajax to make a progress bar?
Complete this requirement in two steps:
One: Write a simple ajax to implement the simplest progress bar function.
Two: Transform this progress bar into a progress bar available for the project.
1: The simplest progress bar
1. The client sends a createXMLHttpRequest request to the server every 2 seconds and gets the progress data returned by the server. Based on the data returned by the server, use javascript to update the width of a table.
This simulates a progress bar.
progressBar.html.The content is as follows:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Ajax Progress Bar</title>
<script type="text/javascript">...
var xmlHttp;
var key;
function createXMLHttpRequest() ...{
if (window.ActiveXObject) ...{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) ...{
xmlHttp = new XMLHttpRequest();
}
}
function go() ...{
createXMLHttpRequest();
clearBar();
var url = "ProgressBarServlet?task=create";
var button = document.getElementById("go");
button.disabled = true;
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = goCallback;
xmlHttp.send(null);
}
function goCallback() ...{
if (xmlHttp.readyState == 4) ...{
if (xmlHttp.status == 200) ...{
setTimeout("pollServer()", 2000);
}
}
}
function pollServer() ...{
createXMLHttpRequest();
var url = "ProgressBarServlet?task=poll&key=" + key;
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = pollCallback;
xmlHttp.send(null);
}
function pollCallback() ...{
if (xmlHttp.readyState == 4) ...{
if (xmlHttp.status == 200) ...{
var percent_complete = xmlHttp.responseXML.getElementsByTagName("percent")[0].firstChild.data;
var progress = document.getElementById("progress");
var progressPersent = document.getElementById("progressPersent");
progress.width = percent_complete + "%";
progressPersent.innerHTML = percent_complete + "%";
if (percent_complete < 100) ...{
setTimeout("pollServer()", 2000);
} else ...{
document.getElementById("complete").innerHTML = "Complete!";
//document.getElementById("go").disabled = false;
}
}
}
}
function clearBar() ...{
var progress_bar = document.getElementById("progressBar");
var progressPersent = document.getElementById("progressPersent");
var complete = document.getElementById("complete");
progress_bar.style.visibility = "visible"
progressPersent.innerHTML = " ";
complete.innerHTML = "Begin to upload this file...";
}
</script>
</head>
<body>
<div id="progressBar" style="padding:0px;border:solid black 0px;visibility:hidden">
<table width="300" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td align="center" id="progressPersent">86%</td>
</tr>
<tr>
<td>
<table width="100%" border="1" cellspacing="0" cellpadding="0" bordercolor="#000000">
<tr>
<td>
<table width="1%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FF0000" id="progress">
<tr>
<td> </td>
</tr>
</table></td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center" id="complete">completed</td>
</tr>
</table>
</div>
<input id = "go" name="run" type="button" value="run" onClick="go();">
</body>
</html>
2: A simulated servlet: ProgressBarServlet1. java, the content is as follows:
package com.cyberobject.lcl.ajax;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
*
* @author nate
* @version
*/
public class ProgressBarServlet extends HttpServlet {
private int counter = 1;
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String task = request.getParameter("task");
String res = "";
if (task.equals("create")) {
res = "<key>1</key>";
counter = 1;
}
else {
String percent = "";
switch (counter) {
case 1: percent = "10"; break;
case 2: percent = "23"; break;
case 3: percent = "35"; break;
case 4: percent = "51"; break;
case 5: percent = "64"; break;
case 6: percent = "73"; break;
case 7: percent = "89"; break;
case 8: percent = "100"; break;
}
counter++;
res = "<percent>" + percent + "</percent>";
}
PrintWriter out = response.getWriter();
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
out.println("<response>");
out.println(res);
out.println("</response>");
out.close();
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/** Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}
}
3: On the web. Configure the servlet mapping in xml:
<!-- Action Servlet Mapping -->
<servlet>
<servlet-name>ProgressBarServlet</servlet-name>
<display-name>ProgressBarServlet</display-name>
<servlet-class>com.cyberobject.lcl.ajax.ProgressBarServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProgressBarServlet</servlet-name>
<url-pattern>/ProgressBarServlet</url-pattern>
</servlet-mapping>
At this point the progress bar is ready to run. The next step is to port it to our system.
two:
1: In the class DbOperater that writes the database, add a progress attribute
private int progress;
2: In the class that writes the database, add a getProgress() method:
public int getProgress()
{
return progress;
}
3: In the for loop of writing the library, progress++;
4: Call the DbOperater's getProgress() method in the servlet that calls the DbOperater, thus providing real-time data for the progress bar.
5: In addition: servlet's doGet() is used to obtain progress data, and doPost() is used to upload files and write library operations. The division of labor between each other is clear.
This is archived.