Servlet 3.0 虽然支持异步请求处理,但却只允许使用传统 I/O,这会限制应用程序的可扩展性。在普通的应用程序中,ServletInputStream 是在 while 循环中进行读取:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
ServletInputStream input = request.getInputStream();
byte[] b = new byte[1024];
int len = -1;
while ((len = input.read(b)) != -1) {
//. . .
}
}
如果读取数据阻塞或者读取数据的速度很慢,那么服务器的线程将会一直等待读取数据。这种情况在通过 ServletOutputStream 写出数据的时候也会遇到。这将会限制 Web 容器的可扩展性。
非阻塞 I/O(Nonblocking I/O)允许开发者只在数据准备好的时候再进行读写操作。此功能不仅增加了服务器的扩展性还增加了服务器可处理的连接数。非阻塞 I/O 只允许在异步 Servlet、异步 Filter 和上传处理的时候使用。
Servlet 3.1 加入了非阻塞 I/O 并且引入了两个新的接口 ReadListener 和 WriteListener。这些接口有回调方法,当数据准备好的时候会被调用。 例如,在 Servlet 的 doGet 方法中可以编写下面的代码:
AsyncContext context = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new MyReadListener(input, context));
调用 setXXXListener 方法将会使用非阻塞 I/O 取代传统 I/O。 ReadListener 有三个回调方法:
- onDataAvailable - 在数据没有阻塞,已经完全准备好可以读取的时候调用。
- onAllDataRead - 所有数据读取完成后调用。
- onError - 请求中发生错误的时候调用。
@Override
public void onDataAvailable() {
try {
StringBuilder sb = new StringBuilder();
int len = -1;
byte b[] = new byte[1024];
while (input.isReady() && (len = input.read(b)) != -1) {
String data = new String(b, 0, len);
}
} catch (IOException ex) {
//. . .
}
}
@Override
public void onAllDataRead() {
context.complete();
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
context.complete();
}
在上面的代码中 onDataAvailable 将会在数据没有阻塞的时候调用。ServletInputStream.isReady 方法用来检查数据是否已经准备好可被无阻塞读取。context.complete 方法在 onAllDataRead 和 onError 方法中调用,用来通知 servlet 上下文环境数据读取操作已经完成。ServletInputStream.isFinished 方法可以用于检查非阻塞读取的状态。
只允许一个 ReadListener 注册到 ServletIntputStream 中。
WriteListener 有两个回调方法:
- onWritePossible - 当数据准备好进行无阻塞写出的时候调用。
- onError - 当操作出错的时候调用。
只允许一个 WriteListener 注册到 ServletOutputStream 中。ServletOutputStream.canWrite 方法可用于检测数据是否已经准备好进行无阻塞写出。
文章来源:
http://www.aptusource.org/2014/04/java-ee-7-servlet-nonblocking-io/
分享到:
相关推荐
Java EE开发指南—基于Spring/Struts/Hibernate的实现 源码 Java EE开发指南—基于Spring/Struts/Hibernate的实现 源码
Java EE开发指南—基于Spring/Struts/Hibernate的实现 源码(第二部分) Java EE开发指南—基于Spring/Struts/Hibernate的实现 源码(第二部分)
经典Java EE企业应用实战:基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 part3
Java EE 中与Servlet 有关的课件
Nonblocking I/O Web Fragments Security Resource Packaging Error Mapping Handling Multipart Requests Upgrade Processing Chapter 3 : JavaServer Faces Facelets Resource Handling ...
本书是一个面向任务的实用指南,通过一系列实用示例来介绍如何开发Java EE 7(java平台企业版7)企业应用。这本书由Oracle的Java EE文档小组成员倾力编写,会让初学者和中缎Java程序员深入了解这个平台。 这个指南包括...
Java EE 7 tutorial 中的examples代码,找了很久才找到下来的,跟Java EE 7 tutorial配套使用,是官方的学习资料。
JAVA EE 开发指南-基于Spring/Struts/Hibernate的实现 (人民有的出版社,王磊杰 崔军波等编著) 一书的源码 由于资源太大,我会一个一个的上传,这个是所有工程的安装使用说明。。。
Develop professional applications in Java EE 7 with this essential reference guide
Java EE 7 Recipes
本书是一个面向任务的实用指南,通过一系列实用示例来介绍如何开发Java EE 7(java平台企业版7)企业应用。这本书由Oracle的Java EE文档小组成员倾力编写,会让初学者和中缎Java程序员深入了解这个平台。 这个指南包括...
Java EE 7 API Documentation 官方英文版(html) 从官方 Java EE SDK 7 安装程序中提取的,原版文档
Java EE WEB 工程师培训------JDBC+Servlet+JSP整合开发
java ee sdk 7 api说明文档
JavaMail的java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream错误 原因: MyEclipse6.5的javaee.jar中的mail包与JavaMail包有冲突。 解决: 在MyEclipse目录下(D:\Program Files\MyEclipse ...
java EE,servlet jsp java web 开发的帮助文档,API
轻量级Java EE企业应用实战_Struts 2_Spring3_Hibernate整合开发(第三版) 注意,由于这个电子书有220M,所以压缩为3部分上传了,请下载全了3个part后解 压。 part1: ...part2: ...
轻量级Java EE企业应用实战_Struts 2_Spring3_Hibernate整合开发(第三版) 注意,由于这个电子书有220M,所以压缩为3部分上传了,请下载全了3个part后解 压。 part1: ...
本书是英文原版的图书 探讨了GlassFish的安装和配置,然后再移动到的Java EE 7的应用程序的开发,涵盖了所有主要的Java EE 7的API。它着重于超越基础开发部署到GlassFish 4应用程序服务器的Java应用程序。本书涵盖了...