2012-02-13 33 views
9

¿Alguien puede enseñarme o dirigirme a un ejemplo de trabajo para satisfacer este requisito?¿Cómo implementar una barra de progreso usando Spring 3 MVC?

Escenario:

  1. elemento de la lista Mi aplicación web está utilizando MVC primavera.
  2. Uno de los servicios que proporciona es que cuando el usuario hace clic en un botón, se produce un proceso de larga ejecución en el servidor. (Consultar la base de datos, escribir archivos, escribir registros, etc ...) este proceso puede tomar unos segundos o unos minutos.
  3. * * Problema * * ¿Cómo puedo implementar el servicio para actualizar el cliente de su progreso.


  4. El servicio devuelve verdadero o falso si el proceso fue exitoso.

Gracias por sus respuestas. Un fragmento de código o un tutorial completo será de gran ayuda.

+2

¿Alguna idea, chicos? Realmente podría usar algo de ayuda. –

+3

Nadie ha tenido el mismo problema que el mío: { –

Respuesta

2

Hay un buen número de formas de manejar un escenario como este. Una forma es modelar el trabajo en términos de un "Proceso", que contiene un "estado", que incluye un porcentaje de finalización.

Si imagina lo que podría parecer en un sitio web, haga clic en el botón para iniciar el proceso y envíe un formulario que comience el proceso y le asigne algún tipo de identidad, casi como si estuviera creando otro tipo de objeto Luego lo redirigiría a una página de "estado del proceso".

La página de estado del proceso consultará el estado del proceso y lo mostrará. Probablemente tenga un parámetro de URL para la identificación del proceso. Tal vez se actualizaría utilizando una llamada AJAX para devolver un porcentaje de progreso.

En el back-end, ahora necesita resolver un par de problemas: conocer el estado actual del proceso N y actualizar el estado del proceso N. Puede lograr esto de varias maneras, incluyendo el almacenamiento del progreso en la base de datos o tener algún tipo de tabla en la memoria de trabajos en ejecución. También podría usar algún tipo de heurística para estimar un porcentaje. Por ejemplo, si se trata de un trabajo de "registrar nuevo usuario", tal vez se haya realizado un 20% si la tabla del usuario tiene una dirección de correo electrónico, 40% si la tabla de avatar del usuario tiene datos para este usuario, etc. No recomiendo esto tanto.

+1

Hola, gracias por la respuesta.Usted indicó en su publicación que hay varias maneras de manejar este problema, pero que solo indicó una. ¿Puedes elaborar sobre las otras soluciones? Actualmente, necesito encontrar una manera de almacenar la información de progreso si sigo este enfoque. De nuevo, gracias por tu respuesta. –

+0

Para descubrir el progreso, necesita hacer una de algunas cosas. O necesita una forma de calcular el progreso cuando el usuario solicita una actualización, o necesita una forma de almacenar el progreso para que cuando el usuario solicite una actualización lo tenga, o necesitará una forma de impulsarlo un mensaje para el usuario de que ha progresado más. Presionar datos a los clientes es un tema bastante complejo en sí mismo, pero le permite no molestarse en almacenar o calcular el progreso. –

2

Aquí es una posible solución a este problema barra de progreso:

task.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%> 

<html> 
    <head> 

     <script src="../js/jquery.min.js"></script> 

     <script> 
      $(document).ready(function() { 
      $.getJSON(window.location.href.concat('/status'), function(data) { 
       if (data === "created") { 

       } else { 
       // task is already being executed 
       refreshProgress(); 
       } 
      }); 
      }); 

      var width = 0; 

      function getProgress() { 
      $.getJSON(window.location.href.concat('/progress'), function(percentage) { 
       $('#progressBar').css('width', percentage+'%'); 
       document.getElementById("label").innerHTML = percentage * 1 + '%'; 
       width = percentage; 
      }); 
      } 

      function start() { 
      $.ajax({ 
       type: "post", 
       data: $('#task').serialize(), 
       success: function(data) { 
       $('#progressBar').css('width', 100+'%'); 
       document.getElementById("label").innerHTML = 100 * 1 + '%'; 

       // do sth with the data after finished task 
       } 
      }); 

      width = 0; 
      $('#progressBar').css('width', 0+'%'); 
      document.getElementById("label").innerHTML = 0 * 1 + '%'; 

      refreshProgress(); 
      } 

      function refreshProgress() { 
      $("#btnStart").prop("disabled",true); 

      var id = setInterval(frame, 1000); 
      function frame() { 
       if (width >= 100) { 
        clearInterval(id); 
        $("#btnStart").prop("disabled",false); 

       } else { 
        getProgress(); 
       } 
      } 
      } 

     </script> 

    </head> 
    <body> 

     <div class="container"> 

     <h2 class="text-center">Progress Bar Example</h2> 
     <div class="progress"> 
      <div id="progressBar" class="progress-bar" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" style="width:0%"> 
      <div id="label">0%</div> 
      </div> 
     </div> 

     <form:form method="POST" commandName="task" cssClass="form-horizontal"> 
     <fieldset> 

     <div class="form-group"> 
      <label class="col-md-4 control-label" for="btnStart">Actions</label> 
      <div class="col-md-8"> 
      <button id="btnStart" name="btnStart" class="btn btn-success">Start</button> 
      <button id="btnStop" name="btnStop" class="btn btn-danger">Stop</button> 
      </div> 
     </div> 

     </fieldset> 
     </form:form> 

     </div> 

     <script> 
     $('#task').submit(function() { 
     start(); 
     return false; 
     }); 
     </script> 

    </body> 
</html> 

TaskController.java

@Controller 
@RequestMapping(value = "/task") 
public class TaskController { 

    private Task task; 

    @RequestMapping("") 
    protected ModelAndView page() { 
     ModelAndView model = new ModelAndView(VIEW_DIR + "task"); 

     if (this.task == null) { 
      this.task = new Task(); 
     } 

     model.addObject("task", this.task); 

     return model; 
    } 

    @RequestMapping(value = "/status", method = GET) 
    public @ResponseBody 
    String getStatus() { 

     return task.getStatus(); 
    } 

    @RequestMapping(value = "/progress", method = GET) 
    public @ResponseBody 
    int getProgress() { 

     return task.getProgress(); 
    } 

    public ModelAndView form(@ModelAttribute Task task) { 

     this.task = task; 

     ModelAndView model = new ModelAndView(VIEW_DIR + "task"); 

     task.execute(); 

     model.addObject("task", this.task); 

     return model; 
    } 

} 

Task.java

public class Task { 

    private int total; 
    private int progress; 
    private String status; 

    public Task() { 
     this.status = "created"; 

     // TODO get total here or pass via form 
    } 

    public void execute() { 

     status = "executing"; 

     int i = 0; 

     while (i < total && status.equals("executing")) { 

      progress = (100 * (i + 1)/total); 

      i++; 
     } 
    } 

    public int getTotal() { 
     return total; 
    } 

    public void setTotal(int total) { 
     this.total = total; 
    } 

    public int getProgress() { 
     return progress; 
    } 

    public void setProgress(int progress) { 
     this.progress = progress; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 
} 
Cuestiones relacionadas