2012-02-13 25 views
9

Czy ktoś może mnie nauczyć lub wskazać działający przykład, aby spełnić ten wymóg.Jak zaimplementować pasek postępu za pomocą Spring 3 MVC?

Scenariusz:

  1. przedmiot My Web App jest za pomocą sprężyny MVC.
  2. Jedną z oferowanych przez nią usług jest to, że po kliknięciu przycisku na serwerze zostanie uruchomiony długo trwający proces. (Baza danych zapytań, zapisywanie plików, zapisywanie dzienników itd.) Proces ten może potrwać kilka sekund lub kilka minut.
  3. * * Problem * * Jak mogę wdrożyć usługę w celu zaktualizowania klienta o jej postępach.


  4. Usługa zwraca wartość true lub false, jeśli proces zakończył się pomyślnie.

Dzięki za odpowiedzi. Fragment kodu lub pełny samouczek będą najbardziej pomocne.

+2

Jakieś pomysły? Naprawdę mógłbym skorzystać z pomocy. –

+3

Nikt nigdy nie napotkał tego samego problemu, co mój: { –

Odpowiedz

2

Istnieje wiele sposobów radzenia sobie z takim scenariuszem. Jednym ze sposobów jest modelowanie pracy w kategoriach "Procesu", który zawiera "status", w tym procent ukończenia.

Jeśli wyobrażasz sobie, jak to może wyglądać na stronie internetowej, kliknięcie przycisku, aby rozpocząć proces, spowoduje przesłanie formularza rozpoczynającego proces i przypisującego do niego pewną tożsamość, prawie tak jak w przypadku tworzenia innego rodzaju przedmiotu. Następnie przekieruje Cię na stronę "statusu procesu".

Strona stanu procesu zapyta o status procesu i wyświetli go. Prawdopodobnie będzie mieć parametr adresu URL dla identyfikatora procesu. Być może zaktualizuje się za pomocą wywołania AJAX, aby zwrócić procent postępu.

W backendie, musisz rozwiązać kilka problemów: dowiedzieć się aktualny status procesu N i aktualizować status procesu N. Możesz to zrobić na wiele sposobów, w tym zapisując postęp w baza danych lub posiadająca tabelę uruchomionych zadań w pamięci. Możesz także użyć heurystyki do oszacowania procentu. Na przykład, jeśli jest to zadanie "zarejestruj nowego użytkownika", być może jest to wykonane w 20%, jeśli tabela użytkownika ma adres e-mail, 40%, jeśli tabela avatara użytkownika zawiera dane dla tego użytkownika itp. Nie polecam to tyle.

+1

Cześć Dzięki za odpowiedź.W swoim poście zaznaczyłeś, że istnieje wiele sposobów na rozwiązanie tego problemu, ale podałeś tylko jeden. Czy możesz rozwinąć inne rozwiązania? Obecnie muszę znaleźć sposób na zapisanie informacji o postępie, jeśli zastosuję się do tego podejścia. Jeszcze raz dziękuję za odpowiedź. –

+0

Aby dowiedzieć się postępu, musisz zrobić jedną z kilku rzeczy. Potrzebny jest ci sposób obliczania postępu, gdy użytkownik prosi o aktualizację, lub potrzebujesz sposobu na zapisanie postępu, tak aby kiedy użytkownik prosi o aktualizację, będziesz go mieć, lub będziesz potrzebował sposobu na wypychanie wiadomość dla użytkownika, że ​​zrobiłeś większy postęp. Przesyłanie danych do klientów jest dość skomplikowanym tematem, ale pozwoliłoby ci nie zajmować się przechowywaniem ani obliczaniem postępu. –

2

Oto możliwe rozwiązanie tego problemu pasek postępu:

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; 
    } 
} 
Powiązane problemy