1

この質問に答える投稿に出くわしましたが、プログラムにどのように実装できるかわかりません。私の要件は次のとおりです。

jsp ページから、ajax 呼び出しを使用してサーブレットを呼び出します。

$(document).on('click' , '#gettopevents' , function(event) {


            var field = $("input[name = 'field']").val(); 

            if(field === "")
            {
                $('#responsemsg').html("enter a field");
            }
            else
            {
                var dataform = { 'field' : field };

                $.ajax({
                        url : 'GetAllLogs',
                        type : 'POST' , 
                        data : dataform , 
                        success : function(response) {
                            $('#displaylist').load('listgeneration.jsp');
                        },
                        error : function(){
                            alert("error");
                        }
                });
            }

            event.preventDefault();
    });

サーブレットの実行はインテンス プロセスであり、時間がかかるため、サーブレットの実行ステータスに関してプログレス バーをユーザーに表示する必要があります。より具体的には、次のようにする必要があります。

@WebServlet("/GetAllLogs")
public class GetAllLogs extends HttpServlet
{
    public void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException , IOException  
    {
          PrintWriter obj = response.getWriter();
          obj.print(10);
          // at this point i need to set the progress bar value to 10%

          ....
          ....

          obj.print(40);
          // at this point i need to change the progress bar value to 40%
         .....
         .....

          obj.print(100);
           //at this point i neet to change the progress bar value to 100%
    }
}

基本的に、サーブレットの値を印刷するためにステータスバーを更新する必要があります。このアプローチは可能ですか、どうすればよいですか。前もって感謝します

4

1 に答える 1

3

基本的な手順は次のとおりです。

  1. 最初の ajax 呼び出しで長時間実行プロセスが開始され、すぐに戻ります
  2. 長時間実行されるプロセスは、所要時間を自己認識しており、進行状況を報告*できます。
  3. 別のエンドポイントは、長時間実行プロセスのステータスを提供します。したがって、プログレスバーに表示するデータを取得するために、1 秒ごとに (または妥当な範囲で) 別の ajax 呼び出しが呼び出されます。

*これは、セッションに保存されたような単純なものAtomicIntegerであり、長時間実行されるプロセスが作業を行うと更新されます。ただし、長時間実行されるプロセスが他の JVM にある可能性や、ステータスを提供するエンドポイントが他の JVM にある可能性があります。この場合、長期実行プロセスを開始する最初の呼び出しで、プロセスに関連付けられた一意のトークンを提供する必要があります。長時間実行されるプロセスは、トークンをキーとして使用して、データベースなどの一部の共有ストレージを更新します。トークンは、ステータスを検索するためのステータスを提供するエンドポイントに渡されます。

編集して追加のコンテキストを追加する

https://.../api/long/running/process/startへの ajax 呼び出し

この ajax 呼び出しが戻ると、バックエンドのポーリングを開始する別のメソッドが呼び出されます。(この他の投稿に基づいています。)

        $.ajax({
                    url : https://.../api/long/running/process/start,
                    type : 'POST' , 
                    data : dataform , 
                    success : function(response) {
                        pollForLongRunningStatus(response);
                    },
                    error : function(){
                        alert("error");
                    }
            });
        }

        pollForLongRunningStatus(response) {
           $.post('https://.../api/long/running/process/status', function(data) {
           alert(data);  // update the progress bar
           setTimeout(pollForLongRunningStatus, 1000);
          });
        }

開始 URL が以下のクラスによって処理されるとします。このクラスは長時間実行されるプロセスを開始してすぐに戻ることが重要であるため、asnych タスクとして実行する必要があります。(それを行う方法は、バックエンド フレームワークがある場合、そのフレームワークによって異なります。)

@WebServlet("/.../api/long/running/process/start")
public class LongRunningProcessStartHandler extends HttpServlet  {
    public void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException , IOException  {

    AtomicInteger percentComplete = new AtomicInteger(0);
    request.getSession().setAttribute("LONG_RUNNING_PROCESS_STATUS", percentComplete);

    LongRunningProcess lrp = new LongRunningProcess(percentComplete);
    lrp.start();

}

public class LongRunningProcess extends Thread {
   private final AtomicInteger percentComplete;

   public LongRunningProcess(AtomicInteger percentComplete) {
       this.percentComplete = percentComplete;
   }

   public void run() {
       for (int i = 0; i < 100; i++) {
       Thread.sleep(1000);
       percentComplete.incrementAndGet();
   }
}

一方、ステータス URL は完了率を報告するだけです。このクラスが status エンドポイントを処理するとします。

@WebServlet("/.../api/long/running/process/status")
public class LongRunningProcessStatusHandler extends HttpServlet  {
    public void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException , IOException  {

    return request.getSession().getAttribute("LONG_RUNNING_PROCESS_STATUS").get();
}

それが一般的な考え方です。(上記のコードはコンパイルされないため、null セーフにする必要があります。) 値が 100 に達したら、セッションからオブジェクトを削除して、セッションをクリーンに保ちます。

于 2018-03-14T15:30:43.243 に答える