吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:Servlet3.1新增的非阻塞式IO

<%--
网站: <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 kongyeeku@163.com
 * @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 kongyeeku@163.com
 * @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();
    }
}
原文地址:https://www.cnblogs.com/tszr/p/12364108.html