2012-02-13 26 views
9

Bất cứ ai có thể dạy tôi hoặc chỉ dẫn đến một ví dụ làm việc để đáp ứng yêu cầu này.Làm thế nào để triển khai thanh tiến trình bằng Spring MVC 3?

Kịch bản:

  1. List item My Web App đang sử dụng MVC mùa xuân.
  2. Một trong những dịch vụ mà nó cung cấp là khi người dùng nhấp vào một nút, quy trình chạy dài sẽ xảy ra trên máy chủ. (Truy vấn cơ sở dữ liệu, ghi tệp, ghi nhật ký, v.v.) quá trình này có thể mất vài giây hoặc vài phút.
  3. * Vấn đề * * * Làm thế nào tôi có thể thực hiện các dịch vụ để cập nhật cho khách hàng về tiến trình của nó.


  4. Dịch vụ trả về đúng hoặc sai nếu quá trình thành công.

Cảm ơn câu trả lời của bạn. Đoạn mã hoặc hướng dẫn đầy đủ sẽ hữu ích nhất.

+2

Bất kỳ ý tưởng nào? Tôi có thể sử dụng một số sự trợ giúp. –

+3

Không ai từng gặp phải vấn đề tương tự như tôi: { –

Trả lời

2

Có một số cách tốt để xử lý một tình huống như thế này. Một cách là mô hình hóa công việc theo "Quy trình", có chứa "trạng thái", bao gồm cả phần trăm hoàn thành.

Nếu bạn tưởng tượng điều này trông như thế nào trên trang web, việc nhấp vào nút để bắt đầu quá trình sẽ gửi biểu mẫu bắt đầu quá trình và gán một số loại nhận dạng cho quy trình, gần như là bạn đang tạo bất kỳ loại nào khác của đối tượng. Sau đó, nó sẽ chuyển hướng bạn đến trang "trạng thái xử lý".

Trang trạng thái xử lý sẽ truy vấn trạng thái của quy trình và hiển thị nó. Có thể nó sẽ có tham số URL cho ID của quy trình. Nó có lẽ sẽ cập nhật chính nó bằng cách sử dụng một cuộc gọi AJAX để trả về một tỷ lệ phần trăm tiến bộ. Trên backend, bây giờ bạn cần giải quyết một vài vấn đề: tìm ra trạng thái hiện tại của tiến trình N, và cập nhật trạng thái của tiến trình N. Bạn có thể thực hiện điều này theo một số cách, bao gồm lưu trữ tiến trình trong cơ sở dữ liệu hoặc có một số loại bảng trong bộ nhớ của các công việc đang chạy. Bạn cũng có thể sử dụng một số loại heuristic để ước tính một phần trăm. Ví dụ: nếu đó là công việc "đăng ký người dùng mới", có thể 20% được thực hiện nếu bảng của người dùng có địa chỉ email, 40% được thực hiện nếu bảng hình đại diện của người dùng có dữ liệu trong đó cho người dùng này, v.v. điều này nhiều.

+1

Xin chào Cảm ơn bạn đã trả lời.Bạn đã nói trong bài viết của bạn rằng có một số cách để xử lý vấn đề này nhưng bạn chỉ nói một. Bạn có thể xây dựng trên các giải pháp khác không? Hiện tại tôi cần tìm cách lưu trữ thông tin tiến độ nếu tôi làm theo cách tiếp cận này. Một lần nữa cảm ơn bạn đã trả lời. –

+0

Để tìm ra tiến bộ, bạn cần thực hiện một trong một vài điều. Bạn cần một cách để tính toán tiến độ khi người dùng yêu cầu cập nhật hoặc bạn cần một cách để lưu trữ tiến trình để khi người dùng yêu cầu bản cập nhật bạn sẽ có hoặc bạn cần có cách để đẩy một thông báo cho người dùng rằng bạn đã thực hiện nhiều tiến bộ hơn. Việc đẩy dữ liệu đến các máy khách là một chủ đề khá phức tạp, nhưng nó sẽ cho phép bạn không bận tâm đến việc lưu trữ hoặc tiến trình tính toán. –

2

Đây là một giải pháp khả thi cho vấn đề thanh tiến trình này:

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; 
    } 
} 
Các vấn đề liên quan