<%-- 网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> author yeeku.H.lee kongyeeku@163.com version 1.0 Copyright (C), 2001-2016, yeeku.H.Lee This program is protected by copyright laws. Program Name: Date: --%> <%@ page contentType="text/html; charset=GBK" language="java" session="false"%> <div style="background-color:#ffffdd;height:80px;"> 浏览器提交数据为:${info}<br/> <%=new java.util.Date()%> </div>
<!DOCTYPE html> <html> <head> <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" /> <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>
<?xml version="1.0" encoding="GBK"?> <!-- 定义生成文件的project根元素,默认的target为空 --> <project name="web" basedir="." default=""> <!-- 定义简单属性 --> <property name="src" value="src"/> <property name="classes" value="classes"/> <!-- 定义一组文件和目录集 --> <path id="classpath"> <fileset dir="lib"> <include name="**/*.jar"/> </fileset> <pathelement path="${classes}"/> </path> <!-- 定义compile target,用于编译Java源文件 --> <target name="compile" description="编译Java源文件"> <!-- 先删除classes属性所代表的文件夹 --> <delete dir="${classes}"/> <!-- 创建classes属性所代表的文件夹 --> <mkdir dir="${classes}"/> <copy todir="${classes}"> <fileset dir="${src}"> <exclude name="**/*.java"/> </fileset> </copy> <!-- 编译Java文件,编译后的class文件放到classes属性所代表的文件夹内 --> <javac destdir="${classes}" debug="true" includeantruntime="yes" deprecation="false" optimize="false" failonerror="true"> <!-- 指定需要编译的Java文件所在的位置 --> <src path="${src}"/> <!-- 指定编译Java文件所需要第三方类库所在的位置 --> <classpath refid="classpath"/> </javac> </target> </project>
<?xml version="1.0" encoding="GBK"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> </web-app>
package lee; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee [email protected] * @version 1.0 */ @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(); } }
package lee; import javax.servlet.*; import java.io.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee [email protected] * @version 1.0 */ 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(); } }