>>分享Java Web开发技术,并且对孙卫琴的《Tomcat与Java Web开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 23835 个阅读者 刷新本主题
 * 贴子主题:  Servlet的非阻塞I/O处理方式 回复文章 点赞(0)  收藏  
作者:sunshine    发表时间:2018-08-22 03:54:44     消息  查看  搜索  好友  邮件  复制  引用

Servlet 3.0 虽然支持异步请求处理,但却只允许使用传统 I/O,这会限制应用程序的可扩展性。在普通的应用程序中,ServletInputStream 是在 while 循环中进行读取:

Java代码  收藏代码
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 方法中可以编写下面的代码:

Java代码  收藏代码
AsyncContext context = request.startAsync();  
ServletInputStream input = request.getInputStream();  
input.setReadListener(new MyReadListener(input, context));  

调用 setXXXListener 方法将会使用非阻塞 I/O 取代传统 I/O。 ReadListener 有三个回调方法:

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


Java代码  收藏代码
@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 方法可用于检测数据是否已经准备好进行无阻塞写出。


程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->异常处理
  JavaWeb开发-->自定义JSP标签(Ⅰ)
  JSP与Hibernate开发-->映射一对多关联关系
  Java网络编程-->客户端协议处理框架
  精通Spring-->Vue组件开发高级技术
  Vue3开发-->Vue组件开发基础
  [求助] javax.servlet 不存在
  一个web疑问
  JSP XML 数据处理
  编写Servlet过滤器
  好书推荐:《Tomcat与JavaWeb开发技术详解》第3版
  用信鸽来解释HTTPS协议
  好消息:孙卫琴老师最新制作的JavaWeb开发视频教程在本站发布...
  Tomcat的工作模式和运行模式
  HTTP协议和相应的RFC文档的更新
  SOAP协议介绍
  Tomcat的工作模式和运行模式
  HTML5 简介
  深度介绍响应式编程
  欢迎读者们为《Tomcat与JavaWeb开发技术详解》书的升级提出宝...
  Java Web前端到后台常用框架介绍
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。