完成HttpServletResponse但继续处理
我的情况似乎符合Async Servlet 3.0 / Comet情况,但我需要做的就是在接受传入参数后返回200响应代码(或其他)。
有没有办法让HttpServlet完成http请求/响应握手并继续处理?
就像是…
doPost( req, response ) { // verify input params... response.setStatus( SC_OK ); response.close(); // execute long query }
编辑:看看javax.servlet包 – 我的问题的正确措辞是
我如何提交回复?
在Servlet.isCommitted()中
以下是我处理这种情况的方法:
- 当应用程序启动时,使用
Executors.newFixedThreadPool(numThreads)
创建一个ExecutorService
(还有其他类型的执行程序,但我建议从这个开始) - 在
doPost()
,创建一个Runnable
实例,它将执行所需的处理 – 您的任务 – 并将其提交到ExecutorService
如下所示:executor.execute(task)
- 最后,您应该返回HTTP状态
202 Accepted
,并且如果可能,还应返回一个Location
标头,指示客户端能够检查处理状态的位置。
我强烈建议您阅读Java Concurrency in Practice ,这是一本非常棒且非常实用的书。
关于servlet在后台接受处理请求的可能性,servlet将处理切换到一个单独的线程,然后在后台执行。
使用Spring,您可以使用TaskExecutor调用单独的Thread。 使用spring而非标准JDK 5 java.util.concurrent.Executor
的优点是,如果您在需要使用托管线程(IBM websphere或Oracle weblogic)的应用程序服务器上,您可以使用WorkManagerTaskExecutor
挂钩到CommonJ工作经理。
另一种方法是将长查询逻辑移动到消息驱动Bean或消息驱动的POJO( Spring JMS可以在这里提供帮助),并让servlet简单地在JMS队列上发布消息。 这样做的好处是,如果由于长时间运行的查询而导致Web容器上的负载变得太大,您可以轻松地将MDB移动到不同的(专用)系统上。
您可以在单独的线程中继续处理。
从doPost()
方法返回后,将doPost()
响应。
这个例子可以帮助你
void doPost(){ // do something final ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable() { @Override public void run() { // processing after response } });}