<?xml version="1.0" encoding="GBK"?>
<!-- 定义生成文件的project根元素,默认的target为空 -->
<project name="web" basedir="." default="">

    <!-- 定义简单属性 -->
    <property name="src" value="src"/>
    <property name="classes" value="classes"/>
    <property name="dist" value="dist"/>
    <property name="module" value="crazyit"/>

    <!-- 定义一组文件和目录集 -->
    <path id="classpath">
        <pathelement path="${classes}"/>
    </path>

    <!-- 定义build target,用于编译、并生成Web模块 -->
    <target name="compile" description="编译Java源文件">
        <!-- 先删除classes属性所代表的文件夹 -->
        <delete dir="${classes}"/>
        <!-- 创建classes属性所代表的文件夹 -->
        <mkdir dir="${classes}"/>
        <!-- 编译Java文件,编译后的class文件放到classes属性所代表的文件夹内 -->
        <javac destdir="${classes}" debug="true" includeantruntime="yes"
            deprecation="classes" optimize="false" failonerror="true">
            <!-- 指定需要编译的Java文件所在的位置 -->
            <src path="${src}"/>
            <!-- 指定编译Java文件所需要第三方类库所在的位置 -->
            <classpath refid="classpath"/>
        </javac>
        <!-- 复制文件 -->
        <copy todir="${classes}">
            <fileset dir="${src}">
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>

    <!-- 定义build target,用于编译、并生成Web模块 -->
    <target name="build" depends="compile" description="打包Web模块">
        <!-- 先删除dist属性所代表的文件夹 -->
        <delete dir="${dist}"/>
        <!-- 创建classes属性所代表的文件夹 -->
        <mkdir dir="${dist}"/>
        <!-- 打包第一个Web模块 -->
        <jar destfile="${dist}/${module}.jar"
            basedir="${classes}"
            excludes="**/*.java"/>            
    </target>
</project>
<?xml version="1.0" encoding="GBK"?>
<web-fragment 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-fragment_3_1.xsd" version="3.1">
    <!-- 指定该Web模块的唯一标识 -->
    <name>crazyit</name>
    <listener>
        <listener-class>lee.CrazyitListener</listener-class>
    </listener>
    <ordering>
        <!-- 用配置该Web模块必须位于哪些模块之前加载 -->
        <before>
            <!-- 用于指定位于其他所有模块之前加载 -->
            <others/>
        </before>
    </ordering>
</web-fragment>
package lee;

import javax.servlet.*;
/**
 * 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 CrazyitListener
    implements ServletContextListener
{
    public void contextInitialized(ServletContextEvent sce)
    {
        System.out.println("--------crazyit模块被加载了--------");
    }
    public void contextDestroyed(ServletContextEvent sce)
    {}
}
<?xml version="1.0" encoding="GBK"?>
<web-fragment 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-fragment_3_1.xsd" version="3.1">
    <!-- 指定该Web模块的唯一标识 -->
    <name>crazyit</name>
    <listener>
        <listener-class>lee.CrazyitListener</listener-class>
    </listener>
    <ordering>
        <!-- 用配置该Web模块必须位于哪些模块之前加载 -->
        <before>
            <!-- 用于指定位于其他所有模块之前加载 -->
            <others/>
        </before>
    </ordering>
</web-fragment>
<?xml version="1.0" encoding="GBK"?>
<!-- 定义生成文件的project根元素,默认的target为空 -->
<project name="web" basedir="." default="">

    <!-- 定义简单属性 -->
    <property name="src" value="src"/>
    <property name="classes" value="classes"/>
    <property name="dist" value="dist"/>
    <property name="module" value="leegang"/>

    <!-- 定义一组文件和目录集 -->
    <path id="classpath">
        <pathelement path="${classes}"/>
    </path>

    <!-- 定义build target,用于编译、并生成Web模块 -->
    <target name="compile" description="编译Java源文件">
        <!-- 先删除classes属性所代表的文件夹 -->
        <delete dir="${classes}"/>
        <!-- 创建classes属性所代表的文件夹 -->
        <mkdir dir="${classes}"/>
        <!-- 编译Java文件,编译后的class文件放到classes属性所代表的文件夹内 -->
        <javac destdir="${classes}" debug="true" includeantruntime="yes"
            deprecation="classes" optimize="false" failonerror="true">
            <!-- 指定需要编译的Java文件所在的位置 -->
            <src path="${src}"/>
            <!-- 指定编译Java文件所需要第三方类库所在的位置 -->
            <classpath refid="classpath"/>
        </javac>
        <!-- 复制文件 -->
        <copy todir="${classes}">
            <fileset dir="${src}">
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>

    <!-- 定义build target,用于编译、并生成Web模块 -->
    <target name="build" depends="compile" description="打包Web模块">
        <!-- 先删除dist属性所代表的文件夹 -->
        <delete dir="${dist}"/>
        <!-- 创建classes属性所代表的文件夹 -->
        <mkdir dir="${dist}"/>
        <!-- 打包第一个Web模块 -->
        <jar destfile="${dist}/${module}.jar"
            basedir="${classes}"
            excludes="**/*.java"/>            
    </target>
</project>
<?xml version="1.0" encoding="GBK"?>
<web-fragment 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-fragment_3_1.xsd" version="3.1">
    <!-- 指定该Web模块的唯一标识 -->
    <name>leegang</name>
    <!-- 配置Listener -->
    <listener>
        <listener-class>lee.LeegangListener</listener-class>
    </listener>
    <ordering>
        <!-- 用配置该Web模块必须位于哪些模块之后加载 -->
        <after>
            <!-- 此处可用多个name元素列出该模块必须位于这些模块之后加载 -->
            <name>crazyit</name>
        </after>
    </ordering>
</web-fragment>
package lee;

import javax.servlet.*;
/**
 * 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 LeegangListener
    implements ServletContextListener
{
    public void contextInitialized(ServletContextEvent sce)
    {
        System.out.println("--------leegang模块被加载了--------");
    }
    public void contextDestroyed(ServletContextEvent sce)
    {}
}
<?xml version="1.0" encoding="GBK"?>
<web-fragment 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-fragment_3_1.xsd" version="3.1">
    <!-- 指定该Web模块的唯一标识 -->
    <name>leegang</name>
    <!-- 配置Listener -->
    <listener>
        <listener-class>lee.LeegangListener</listener-class>
    </listener>
    <ordering>
        <!-- 用配置该Web模块必须位于哪些模块之后加载 -->
        <after>
            <!-- 此处可用多个name元素列出该模块必须位于这些模块之后加载 -->
            <name>crazyit</name>
        </after>
    </ordering>
</web-fragment>
<%--
网站: <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"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<ul>
<c:forEach items="${books}" var="book">
    <li>${book}</li>
</c:forEach>
</ul>
<%out.println("业务调用结束的时间:" + new java.util.Date());
if (request.isAsyncStarted()) {
    // 完成异步调用
    request.getAsyncContext().complete();
}%>
<%--
网站: <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" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title> 文件上传 </title>
    <meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<form method="post" action="upload"  enctype="multipart/form-data">
    文件名:<input type="text" id="name" name="name" /><br/>
    选择文件:<input type="file" id="file" name="file" /><br/>
    <input type="submit" value="上传" /><br/>
</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">
    <absolute-ordering>
        <!-- 指定Web模块按如下顺序加载  -->
        <name>leegang</name>
        <name>crazyit</name>
    </absolute-ordering>

    <!--
    <servlet> 
        <servlet-name>async</servlet-name> 
        <servlet-class>lee.AsyncServlet</servlet-class> 
        <async-supported>true</async-supported> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name>async</servlet-name> 
        <url-pattern>/async</url-pattern> 
    </servlet-mapping>
    -->
</web-app>
package lee;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

import java.io.*;
import java.util.*;

/**
 * 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 GetBooksTarget implements Runnable
{
    private AsyncContext actx = null;
    public GetBooksTarget(AsyncContext actx)
    {
        this.actx = actx;
    }
    public void run()
    {
        try
        {
            // 等待5秒钟,以模拟业务方法的执行
            Thread.sleep(5 * 1000);
            ServletRequest request = actx.getRequest();
            List<String> books = new ArrayList<String>();
            books.add("疯狂Java讲义");
            books.add("轻量级Java EE企业应用实战");
            books.add("疯狂Ajax讲义");
            request.setAttribute("books" , books);
            actx.dispatch("/async.jsp");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}
package lee;

import javax.servlet.*;
import javax.servlet.http.*;

import java.io.*;
import java.util.*;

/**
 * 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 MyAsyncListener
    implements AsyncListener
{
    public void onComplete(AsyncEvent event)
        throws IOException
    {
        System.out.println("------异步调用完成------" + new Date());
    }
    public void onError(AsyncEvent event)
        throws IOException
    {}
    public void onStartAsync(AsyncEvent event)
        throws IOException
    {
        System.out.println("------异步调用开始------" + new Date());
    }
    public void onTimeout(AsyncEvent event)
        throws IOException
    {}
}
package lee;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

import java.io.*;
import java.util.*;

/**
 * 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(name="upload" , urlPatterns={"/upload"})
@MultipartConfig
public class UploadServlet extends HttpServlet
{
    public void service(HttpServletRequest request ,
        HttpServletResponse response)
        throws IOException , ServletException
    {
        response.setContentType("text/html;charset=GBK");
        PrintWriter out = response.getWriter();
        request.setCharacterEncoding("GBK");
        // 获取普通请求参数
        String name = request.getParameter("name");
        out.println("普通的name参数为:" + name + "<br/>");
        // 获取文件上传域
        Part part = request.getPart("file");
        // 获取上传文件的文件类型
        out.println("上传文件的的类型为:"
            + part.getContentType() + "<br/>");
        //获取上传文件的大小。
        out.println("上传文件的的大小为:" + part.getSize()  + "<br/>");
        // 获取该文件上传域的Header Name
        Collection<String> headerNames = part.getHeaderNames();
        // 遍历文件上传域的Header Name、Value
        for (String headerName : headerNames)
        {
            out.println(headerName + "--->"
                + part.getHeader(headerName) + "<br/>");
        }
        // 获取包含原始文件名的字符串
        String fileNameInfo = part.getHeader("content-disposition");
        // 提取上传文件的原始文件名
        String fileName = fileNameInfo.substring(
            fileNameInfo.indexOf("filename=\"") + 10 , fileNameInfo.length() - 1);
        // 将上传的文件写入服务器
        part.write(getServletContext().getRealPath("/uploadFiles")
            + "/" + fileName );               //
    }
}
package lee;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

import java.io.*;
import java.util.*;

/**
 * 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
{
    @Override
    public void doGet(HttpServletRequest request
        , HttpServletResponse response)throws IOException,ServletException
    {
        response.setContentType("text/html;charset=GBK");
        PrintWriter out = response.getWriter();
        out.println("<title>异步调用示例</title>");
        out.println("进入Servlet的时间:"
            + new java.util.Date() + ".<br/>");
        // 创建AsyncContext,开始异步调用
        AsyncContext actx = request.startAsync();
        // 设置异步调用的超时时长
        actx.setTimeout(60 * 1000);
        // 启动异步调用的线程,该线程以异步方式执行
        actx.start(new GetBooksTarget(actx));
        out.println("结束Servlet的时间:"
            + new java.util.Date() + ".<br/>");
        out.flush();
    }
}