Servlet——非阻塞IO

Servlet 新特性包括: 强制更改Session Id、非阻塞IO等;

Servlet底层的IO是通过两个流来支持的:

——ServletInputStream

——ServletOutputStream

在Servlet中使用非阻塞IO非常简单,步骤如下:

1.通过ServletRequest 的 startAsync() 开启异步模式

2.通过ServletRequest 获取ServletInputStream ,并为 ServletInputStream 设置监听器(ReadListener实现类)

3.实现监听器,在监听器方法内以非阻塞方式读取数据

Servlet 代码:

@WebServlet(urlPatterns="/async",asyncSupported=true)
public class AsyncServlet extends HttpServlet
{
public void service(HttpServletRequest request ,
HttpServletResponse response)
throws IOException , ServletException
{
response.setContentType("text/html;charset=GBK");
PrintWriter out = response.getWriter();
out.println("<title>非阻塞IO示例</title>");
out.println("进入Servlet的时间:"
+ new java.util.Date() + ".<br/>");
// 创建AsyncContext,开始异步调用
AsyncContext context = request.startAsync();
// 设置异步调用的超时时长
context.setTimeout(60 * 1000);
ServletInputStream input = request.getInputStream();
// 为输入流注册监听器
    input.setReadListener(new MyReadListener(input, context));

out.println("结束Servlet的时间:"
+ new java.util.Date() + ".<br/>");
out.flush();
}
}

MyReadListener 代码:

public class MyReadListener implements ReadListener
{
private ServletInputStream input;
private AsyncContext context;
public MyReadListener(ServletInputStream input , AsyncContext context)
{
this.input = input;
this.context = context;
}


@Override
public void onDataAvailable()
{
System.out.println("数据可用!!");
try
{
// 暂停5秒,模拟读取数据是一个耗时操作。
Thread.sleep(5000);
StringBuilder sb = new StringBuilder();
int len = -1;
byte[] buff = new byte[1024];
// 采用原始IO方式读取浏览器向Servlet提交的数据
while (input.isReady() && (len = input.read(buff)) > 0)
{
String data = new String(buff , 0 , len);
sb.append(data);
}
System.out.println(sb);
// 将数据设置为request范围的属性
context.getRequest().setAttribute("info" , sb.toString());
// 转发到视图页面
context.dispatch("/async.jsp");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
@Override
public void onAllDataRead()
{
System.out.println("数据读取完成");
}
@Override
public void onError(Throwable t)
{
t.printStackTrace();
}
}


async.jsp 

<%@ page contentType="text/html; charset=GBK" language="java"
session="false"%>
<div style="background-color:#ffffdd;height:80px;">
浏览器提交数据为:${info}<br/>
<%=new java.util.Date()%>
</div>

 form.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>  </title>
</head>
<body>
<form action="async" method="post">
用户名:<input type="text" name="name"/><br/>
密码:<input type="text" name="pass"/><br/>
<input type="submit" value="提交">
<input type="reset" value="重设">
</form>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/u014229282/article/details/51088158