`
小巫婆
  • 浏览: 23265 次
文章分类
社区版块
存档分类
最新评论

AsyncContext简介

 
阅读更多

为了支持异步处理,在Servlet 3.0中,在ServletRequest上提供了startAsync()方法:
AsyncContext startAsync() throws java.lang.IllegalStateException;
AsyncContext startAsync(ServletRequest servletRequest,
ServletResponse servletResponse)
throws java.lang.IllegalStateException

这两个方法都会返回AsyncContext接口的实现对象,前者会直接利用原有的请求与响应对象来创建AsyncContext,后者可以传入自行创建的请求、响应封装对象。在调用了startAsync()方法取得AsyncContext对象之后,此次请求的响应会被延后,并释放容器分配的线程。

可以通过AsyncContext的getRequest()、getResponse()方法取得请求、响应对象,此次对客户端的响应将暂缓至调用AsyncContext的complete()或dispatch()方法为止,前者表示响应完成,后者表示将调派指定的URL进行响应。

若要能调用ServletRequest的startAsync()以取得AsyncContext,必须告知容器此Servlet支持异步处理,如果使用@WebServlet来标注,则可以设置其asyncSupported为true。例如:
@WebServlet(urlPatterns = "/some.do", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
...
如果使用web.xml设置Servlet,则可以在<servlet>中设置<async-supported>标签为true:
...
<servlet>
<servlet-name>AsyncServlet</servlet-name>
<servlet-class>cc.openhome.AsyncServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
...

如果Servlet将会进行异步处理,若其前端有过滤器,则过滤器亦需标示其支持异步处理,如果使用@WebFilter,同样可以设置其asyncSupported为true。例如:
@WebFilter(urlPatterns = "/some.do", asyncSupported = true)
public class AsyncFilter implements Filter{
...

如果使用web.xml设置过滤器,则可以设置<async-supported>标签为true:
...
<filter>
<filter-name>AsyncFilter</filter-name>
<filter-class>cc.openhome.AsyncFilter</filter-class>
<async-supported>true</async-supported>
</filter>
...

下面示范一个异步处理的简单例子:
AsyncContextDemo AsyncServlet.java
package cc.openhome;
import java.io.*;
import java.util.concurrent.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;
@WebServlet(name="AsyncServlet", urlPatterns={"/async.do"},
asyncSupported = true)
public class AsyncServlet extends HttpServlet {
private ExecutorService executorService =
Executors.newFixedThreadPool(10);
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=UTF8");
AsyncContext ctx = request.startAsync();
executorService.submit(new AsyncRequest(ctx));
}
@Override
public void destroy() {
executorService.shutdown();
}
}

首先告诉容器,这个Servlet支持异步处理?,对于每个请求,Servlet会取得其AsyncContext?,并释放容器所分配的线程,响应被延后。对于这些被延后响应的请求,创建一个实现Runnable接口的AsyncRequest对象,并将其调度一个线程池(Thread pool)?,线程池的线程数量是固定的,让这些必须长时间处理的请求,在这些有限数量的线程中完成,而不用每次请求都占用容器分配的线程。

AsyncRequest是个实现Runnable的类,其模拟了长时间处理:
AsyncContextDemo AsyncRequest.java
package cc.openhome;
import java.io.PrintWriter;
import javax.servlet.AsyncContext;
public class AsyncRequest implements Runnable {
private AsyncContext ctx;
public AsyncRequest(AsyncContext ctx) {
this.ctx = ctx;
}
@Override
public void run() {
try {
Thread.sleep(10000);
PrintWriter out = ctx.getResponse().getWriter();
out.println("久等了...XD");
ctx.complete();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

请求与响应对象都封装在AsyncContext中,所以AsyncRequest建构时必须接受AsyncContext实例。范例中以暂停线程的方式来模拟长时间处理?,并输出简单的字符串作为响应文字?,最后调用AsyncContext的complete()对客户端完成响应?。

分享到:
评论

相关推荐

    async-hessian:通过Servlet 3.0 AsyncContext导出Hessian服务的方法

    通过Servlet 3.0 AsyncContext导出服务的方法 如何获得? 您可以将其用作Maven依赖项: &lt; groupId&gt;org.jmmo &lt; artifactId&gt;async-hessian &lt; version&gt;1.1 或在以下位置下载最新版本: : 如何使用它? 创建...

    async-servlet-with-filter

    当异步调用的回调返回时,在AsyncContext上调用dispatch() 该请求通过doFilter方法再次分派,这次使用分派类型ASYNC 这次我们调用chain.doFilter() ,并且请求进入servlets doGet()方法。 启动一个新的...

    async-fp:异步功能编程实用程序

    const context = new AsyncContext ( async ( ) =&gt; ( { config : 'async value' } ) ) await context . get ( ) //=&gt; { config: 'async value' } 发布管理 使用 。 当我清空工作流程时,将填写更多详细信息。 当前...

    AsyncIoJaxRsProposal:异步 IO JAX-RS.Next 提案

    资源中异步 I/O 的定义通过资源访问异步 I/O 流的方式是使用通过使用 @AsyncContext 参数注释定义的 RestAsyncContext: 下面是一个资源方法签名的例子: public void doGet(@QueryParam("param") 字符串参数,@...

    java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/ConditionalTagSupport 问题-附件资源

    java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/ConditionalTagSupport 问题-附件资源

    javax.servlet-api-4.0.0-b03.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b07.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b08.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.1.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b05.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b03.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.0-b02.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.0-b01.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b06.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.0-b07.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b09.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.0.1.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-3.1-b04.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

    javax.servlet-api-4.0.0-b06.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【javax.servlet-api-***.jar中文文档.zip】 中包含: ...javax.servlet.AsyncContext javax.servlet.AsyncEvent javax.servlet.AsyncListener ...... ```

Global site tag (gtag.js) - Google Analytics