En un proyecto reciente, había una función de carga: cargar un archivo CVS, luego analizar el archivo y escribirlo en la base de datos. Dado que a menudo es necesario cargar archivos grandes, los clientes suelen tardar 40 minutos en completar esta función. Durante el proceso, la página tampoco aparece y la experiencia del usuario es muy mala.
¿Por qué no utilizar ajax para crear una barra de progreso?
Complete este requisito en dos pasos:
Uno: escriba un ajax simple para implementar la función de barra de progreso más simple.
Dos: Transforme esta barra de progreso en una barra de progreso disponible para el proyecto.
1: la barra de progreso más simple
1. El cliente envía una solicitud createXMLHttpRequest al servidor cada 2 segundos y obtiene los datos de progreso devueltos por el servidor. Según los datos devueltos por el servidor, use javascript para actualizar el ancho de una tabla.
Esto simula una barra de progreso.
ProgressBar.html.El contenido es el siguiente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<cabeza>
<title>Barra de progreso de Ajax</title>
<tipo de script="texto/javascript">...
var xmlHttp;
clave var;
función createXMLHttpRequest() ...{
si (ventana.ActiveXObject) ...{
xmlHttp = nuevo ActiveXObject("Microsoft.XMLHTTP");
}
de lo contrario si (ventana.XMLHttpRequest) ...{
xmlHttp = nueva XMLHttpRequest();
}
}
función ir() ...{
crearXMLHttpRequest();
borrarbar();
var url = "ProgressBarServlet? tarea = crear";
botón var = document.getElementById("ir");
botón.disabled = verdadero;
xmlHttp.open("OBTENER", URL, verdadero);
xmlHttp.onreadystatechange = goCallback;
xmlHttp.send(nulo);
}
función goCallback() ...{
si (xmlHttp.readyState == 4) ...{
si (xmlHttp.status == 200) ...{
setTimeout("pollServer()", 2000);
}
}
}
función pollServer() ...{
crearXMLHttpRequest();
var url = "ProgressBarServlet?task=poll&key=" + clave;
xmlHttp.open("OBTENER", URL, verdadero);
xmlHttp.onreadystatechange = pollCallback;
xmlHttp.send(nulo);
}
función pollCallback() ...{
si (xmlHttp.readyState == 4) ...{
si (xmlHttp.status == 200) ...{
var percent_complete = xmlHttp.responseXML.getElementsByTagName("porcentaje")[0].firstChild.data;
var progreso = document.getElementById("progreso");
var progresoPersent = document.getElementById("progresoPersent");
progreso.ancho = porcentaje_completo + "%";
ProgressPersent.innerHTML = porcentaje_completo + "%";
si (porcentaje_completo < 100) ...{
setTimeout("pollServer()", 2000);
} demás ...{
document.getElementById("completo").innerHTML = "¡Completo!";
//document.getElementById("ir").disabled = false;
}
}
}
}
función borrarBar() ...{
var progreso_bar = document.getElementById("progressBar");
var progresoPersent = document.getElementById("progresoPersent");
var completo = document.getElementById("completo");
Progress_bar.style.visibility = "visible"
ProgressPersent.innerHTML = " ";
complete.innerHTML = "Comenzar a cargar este archivo...";
}
</script>
</cabeza>
<cuerpo>
<div id="progressBar" style="padding:0px;border:negro sólido 0px;visibilidad:oculto">
<table width="300" border="0" cellspace="0" cellpadding="0" align="center">
<tr>
<td align="center" id="progressPersent">86%</td>
</tr>
<tr>
<td>
<table width="100%" border="1" cellspace="0" cellpadding="0" bordercolor="#000000">
<tr>
<td>
<table width="1%" border="0" cellspace="0" cellpadding="0" bgcolor="#FF0000" id="progreso">
<tr>
<td></td>
</tr>
</tabla></td>
</tr>
</tabla>
</td>
</tr>
<tr>
<td align="center" id="completo">completado</td>
</tr>
</tabla>
</div>
<input id = "ir" nombre="ejecutar" tipo="botón" valor="ejecutar" onClick="ir();">
</cuerpo>
</html>
2: Un servlet simulado: ProgressBarServlet1. java, el contenido es el siguiente:
paquete com.cyberobject.lcl.ajax;
importar java.io.*;
importar javax.servlet.*;
importar javax.servlet.http.*
/**
*
* @autor nate
* @versión
*/
clase pública ProgressBarServlet extiende HttpServlet {
contador int privado = 1;
/** Maneja el método HTTP <code>GET</code>.
* @param solicitud de servlet
* @param respuesta del servlet de respuesta
*/
doGet vacío protegido (solicitud HttpServletRequest, respuesta HttpServletResponse)
lanza ServletException, IOException {
Tarea de cadena = request.getParameter("tarea");
Cadena res = "";
si (tarea.equals("crear")) {
res = "<clave>1</clave>";
contador = 1;
}
demás {
Porcentaje de cadena = "";
cambiar (contador) {
caso 1: porcentaje = "10";
caso 2: porcentaje = "23";
caso 3: porcentaje = "35";
caso 4: porcentaje = "51";
caso 5: porcentaje = "64";
caso 6: porcentaje = "73";
caso 7: porcentaje = "89";
caso 8: porcentaje = "100";
}
contador++;
res = "<porcentaje>" + porcentaje + "</percent>";
}
PrintWriter fuera = respuesta.getWriter();
respuesta.setContentType("texto/xml");
respuesta.setHeader("Control de caché", "sin caché");
out.println("<respuesta>");
salida.println(res);
out.println("</response>");
fuera.cerrar();
}
/** Maneja el método HTTP <code>POST</code>.
* @param solicitud de servlet
* @param respuesta del servlet de respuesta
*/
Protegido void doPost (solicitud HttpServletRequest, respuesta HttpServletResponse)
lanza ServletException, IOException {
doGet(solicitud, respuesta);
}
/** Devuelve una breve descripción del servlet.
*/
cadena pública getServletInfo() {
devolver "Breve descripción";
}
}
3: En la web. Configure el mapeo de servlets en xml:
<!-- Mapeo de servlet de acción -->
<servlet>
<nombre-servlet>ProgressBarServlet</nombre-servlet>
<display-name>ProgressBarServlet</display-name>
<servlet-clase>com.cyberobject.lcl.ajax.ProgressBarServlet</servlet-clase>
</servlet>
<servlet-mapping>
<nombre-servlet>ProgressBarServlet</nombre-servlet>
<url-pattern>/ProgressBarServlet</url-pattern>
</servlet-mapping>
En este punto, la barra de progreso está lista para ejecutarse. El siguiente paso es portarlo a nuestro sistema.
dos:
1: En la clase DbOperater que escribe la base de datos, agrega un atributo de progreso
progreso int privado;
2: en la clase que escribe la base de datos, agregue un método getProgress():
público int getProgress()
{
progreso de retorno;
}
3: En el bucle for de escritura de la biblioteca, progreso++;
4: Llame al método getProgress () de DbOperater en el servlet que llama a DbOperater, proporcionando así datos en tiempo real para la barra de progreso.
5: Además: doGet () del servlet se usa para obtener datos de progreso y doPost () se usa para cargar archivos y escribir operaciones de biblioteca. La división del trabajo entre ellos es clara.
Esto está archivado.