Java 在web应用程序中实现长时间运行的流程

Java 在web应用程序中实现长时间运行的流程,java,jquery,spring,Java,Jquery,Spring,出于某种原因,我在谷歌上找不到解决方案。我在web应用程序中有一个选项,可以上传大量数据(在文件中),并通过后端处理(我们使用Java/Spring)来存储这些数据。大概需要5分钟。是否有人知道用户可以通过什么方式启动此过程并执行其他操作,以及何时完成以通知用户 我正在考虑的一个解决方案(不确定是否有更好的一次,这就是我在这里的原因)是进行一个AJAX调用(我们碰巧使用jQuery库),它将文件传递给控制器,然后,当控制器处理文件时,它会定期向流发送一些小的内容,这样就不会发生超时,然后一旦超时

出于某种原因,我在谷歌上找不到解决方案。我在web应用程序中有一个选项,可以上传大量数据(在文件中),并通过后端处理(我们使用Java/Spring)来存储这些数据。大概需要5分钟。是否有人知道用户可以通过什么方式启动此过程并执行其他操作,以及何时完成以通知用户


我正在考虑的一个解决方案(不确定是否有更好的一次,这就是我在这里的原因)是进行一个AJAX调用(我们碰巧使用jQuery库),它将文件传递给控制器,然后,当控制器处理文件时,它会定期向流发送一些小的内容,这样就不会发生超时,然后一旦超时完成,它会通知用户它将通知的web应用程序。

我们可以使用jquery ajax吗

success: function(xhr_data) {
  console.log(xhr_data);
  if (xhr_data.status == 'pending') {

    if (cnt < 6) {
        cnt++;
        setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
    }

  } else {
    success(xhr_data);
  }
}
success:函数(xhr\u数据){
console.log(xhr_数据);
如果(xhr_data.status=='pending'){
if(cnt<6){
cnt++;
setTimeout(function(){ajax_request();},15000);//等待15秒,然后再次调用ajax请求
}
}否则{
成功(xhr_数据);
}
}

我们可以使用jquery ajax来实现这一点吗

success: function(xhr_data) {
  console.log(xhr_data);
  if (xhr_data.status == 'pending') {

    if (cnt < 6) {
        cnt++;
        setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
    }

  } else {
    success(xhr_data);
  }
}
success:函数(xhr\u数据){
console.log(xhr_数据);
如果(xhr_data.status=='pending'){
if(cnt<6){
cnt++;
setTimeout(function(){ajax_request();},15000);//等待15秒,然后再次调用ajax请求
}
}否则{
成功(xhr_数据);
}
}

<代码> > P>我会考虑推送通知SaaS,如

客户端向服务器发送请求需要一段时间:

POST /process-file
服务器响应

HTTP 202 Accepted

{ channelName:'some-channel', events:[{name:'my-processing-complete-event'}] }
在客户端上,使用JavaScript订阅频道并收听:

var channel = pusher.subscribe('some-channel');
channel.bind('my-processing-complete-event', function(message){
  alert(message);
});
在服务器上,处理完成后,通知推送服务,然后推送服务通知所有客户端

pusher.trigger("some-channel", "my-processing-complete-event", "processing done");

我会考虑推送通知SaaS,如

客户端向服务器发送请求需要一段时间:

POST /process-file
服务器响应

HTTP 202 Accepted

{ channelName:'some-channel', events:[{name:'my-processing-complete-event'}] }
在客户端上,使用JavaScript订阅频道并收听:

var channel = pusher.subscribe('some-channel');
channel.bind('my-processing-complete-event', function(message){
  alert(message);
});
在服务器上,处理完成后,通知推送服务,然后推送服务通知所有客户端

pusher.trigger("some-channel", "my-processing-complete-event", "processing done");

我认为最好的解决办法如下。有一个监视后端任务的DB表。前端通过后端服务定期查询该表的状态。一旦状态完成,它就会通知用户。

我认为最好的解决方案如下。有一个监视后端任务的DB表。前端通过后端服务定期查询该表的状态。一旦状态完成,它就会通知用户。

我最近不得不解决这样一个问题,这真的很容易。他就是我这么说的原因

  • 使用HTTP 1.1协议,服务器连接将保持打开状态,直到返回请求的最后一个资源。任何兼容HTTP 1.1的web服务器都可以在幕后为您做到这一点,而无需您付出任何努力。这本身就让你的问题更容易解决

  • 使用Servlet3.0,您应该利用新的异步特性(尽管您可以在servlet<3.0中自己推出类似的功能)。服务器为来自其线程池的每个传入请求分配一个新线程。然后使用您自己的自定义线程池,将此请求线程的处理与asyncContext一起移交给自定义线程。您自己的线程将处理这个长时间运行的进程,服务器的线程将立即返回以处理其他请求。asyncContext包含原始请求/响应对象,但它们处于“冻结”状态。当长时间运行的进程完成时,它将调用asyncContext.complete()方法。此操作将提交处于“冻结”状态的原始请求/响应

  • 对于客户机来说,这个异步过程看起来像是服务器要花很长时间才能响应,因此客户机将耐心地等待响应。你不需要做任何不寻常的事情

  • 在客户端,调用ajax请求的任何方法都已足够。不需要轮询。客户将愉快地坐着等待响应。xmlHttpRequest对象的“readyState”属性将为您解决这个问题。服务器提交响应后,“readyState”值将更改为4,从那里您可以更新UI

  • 在服务器端,您可能应该将具有该方法的类包装到一个内部类中的长时间运行的流程中,该内部类将调用长时间运行的流程,并保存一个布尔属性,例如“running=true/false”。这样,如果在你长期运行的请求中,有人试图再次调用相同的进程,他们将能够知道它是否已经运行。这比你要求的要详细


    无论如何,我希望我能帮助你,同时也给了你一些前进的线索。

    我最近不得不解决一个类似的问题,这真的很容易。他就是我这么说的原因

  • 使用HTTP 1.1协议,服务器连接将保持打开状态,直到返回请求的最后一个资源。任何兼容HTTP 1.1的web服务器都可以在幕后为您做到这一点,而无需您付出任何努力。这本身就让你的问题更容易解决

  • 使用Servlet3.0,您应该利用新的异步特性(尽管您可以在servlet<3.0中自己推出类似的功能)。服务器为来自其线程池的每个传入请求分配一个新线程。然后使用您自己的自定义线程池,将此请求线程的处理与asyncContext一起移交给自定义线程。您自己的线程将处理这个长时间运行的进程,服务器的线程将立即返回以处理其他请求。asyncContext包含原始请求/响应对象,但它们处于“冻结”状态。当长时间运行的流程完成时,它将调用