[Java EE 7] Servlet 非阻塞 I/O

Servlet 3.1 引入了非阻塞I/O功能,通过ReadListener和WriteListener接口实现了数据准备就绪时的回调机制,增强了服务器处理连接的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 有三个回调方法:

[list]
[*] onDataAvailable - 在数据没有阻塞,已经完全准备好可以读取的时候调用。
[*] onAllDataRead - 所有数据读取完成后调用。
[*] onError - 请求中发生错误的时候调用。
[/list]

@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 有两个回调方法:

[list]
[*] onWritePossible - 当数据准备好进行无阻塞写出的时候调用。
[*] onError - 当操作出错的时候调用。
[/list]

只允许一个 WriteListener 注册到 ServletOutputStream 中。ServletOutputStream.canWrite 方法可用于检测数据是否已经准备好进行无阻塞写出。

文章来源:[url]http://www.aptusource.org/2014/04/java-ee-7-servlet-nonblocking-io/[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值