java 完成 HttpServletResponse 但继续处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2367650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 20:48:20  来源:igfitidea点击:

Finishing a HttpServletResponse but continue processing

javahttpservletscomet

提问by Stevko

I have a situation that seems to fit the Async Servlet 3.0 / Comet situation but all I need to do is return a 200 response code (or other) after accepting the incoming parameters.

我的情况似乎适合 Async Servlet 3.0 / Comet 情况,但我需要做的就是在接受传入参数后返回 200 响应代码(或其他)。

Is there a way for a HttpServlet to complete the http request/response handshake and yet continue processing?

有没有办法让 HttpServlet 完成 http 请求/响应握手并继续处理?

Something like...

就像是...

doPost( req, response ) {
   // verify input params...
   response.setStatus( SC_OK );
   response.close();
   // execute long query
}     

EDIT: Looking at the javax.servlet package - the proper phrasing to my question is

编辑:查看 javax.servlet 包 - 我的问题的正确措辞是

How do I commit a response?

我如何提交回复?

as in Servlet.isCommitted()

如 Servlet.isCommitted()

采纳答案by Avi Flax

Here's how I've handled this situation:

这是我处理这种情况的方法:

  1. When the app starts up, create an ExecutorServicewith Executors.newFixedThreadPool(numThreads)(there are other types of executors, but I suggest starting with this one)
  2. In doPost(), create an instance of Runnablewhich will perform the desired processing - your task - and submit it to the ExecutorServicelike so: executor.execute(task)
  3. Finally, you should return the HTTP Status 202 Accepted, and, if possible, a Locationheader indicating where a client will be able to check up on the status of the processing.
  1. 当应用程序启动时,创建一个ExecutorServicewith Executors.newFixedThreadPool(numThreads)(还有其他类型的 executor,但我建议从这个开始)
  2. 在 中doPost(),创建一个实例,Runnable该实例将执行所需的处理 - 您的任务 - 并将其提交给ExecutorService这样的:executor.execute(task)
  3. 最后,您应该返回 HTTP 状态202 Accepted,如果可能,还应返回一个Location标头,指示客户端将能够检查处理状态的位置。

I highlyrecommend you read Java Concurrency in Practice, it's a fantastic and very practical book.

强烈建议您阅读Java Concurrency in Practice,这是一本非常棒且非常实用的书。

回答by pajton

You can continue processing in a separate Thread.

您可以在单独的线程中继续处理。

The response is commited once you return from doPost()method.

一旦您从doPost()方法返回,就会提交响应。

回答by beny23

On possibility for your servlet to accept a request for processing in the background, is for the servlet to hand off processing to a separate thread which then executes in the background.

您的 servlet 接受后台处理请求的可能性是,servlet 将处理移交给一个单独的线程,然后该线程在后台执行。

Using Spring, you can invoke a separate Thread using the a TaskExecutor. The advantage of using spring over standard JDK 5 java.util.concurrent.Executoris that if you're on application servers that need to use managed threads (IBM websphere or Oracle weblogic), you can use the WorkManagerTaskExecutorto hook into the CommonJ work managers.

使用 Spring,您可以使用TaskExecutor调用单独的线程。使用 spring 优于标准 JDK 5 的优势java.util.concurrent.Executor在于,如果您在需要使用托管线程(IBM websphere 或 Oracle weblogic)的应用服务器上,您可以使用WorkManagerTaskExecutor挂钩到 CommonJ 工作管理器。

Another alternative would be to move the long query logic into a Message Driven Bean or Message Driven POJO (Spring JMScan help here) and let the servlet simply post a message on a JMS queue. That would have the advantage that should the load on your web container become too great because of your long running query, you could easily move the MDB onto a different (dedicated) system.

另一种替代方法是将长查询逻辑移动到消息驱动 Bean 或消息驱动 POJO(Spring JMS可以在此处提供帮助)并让 servlet 简单地在 JMS 队列上发布消息。这样做的好处是,如果您的 Web 容器上的负载因长时间运行的查询而变得太大,您可以轻松地将 MDB 移动到不同的(专用)系统上。

回答by wiem

This example can help

这个例子可以帮助

void doPost(){
    // do something
   final ExecutorService executor = Executors.newSingleThreadExecutor();
      executor.execute(new Runnable() {
          @Override
          public void run() {
              // processing after response
          }
      });}