• 学习Servlet中的异步处理 —— Servlet3.0中的Async支持


    servlet的@WebServlet注解写法:

    /**
     * asyncSupported属性默认是false,如果需要开启支持异步处理功能,需要设置为true
     */
    @WebServlet(name = "ServletAsyn", urlPatterns = "/ServletAsyn", asyncSupported = true)
    

    AsynFilter的@WebServlet注解写法:

    @WebFilter(filterName="AsynFilter",asyncSupported=true,value={"/ServletAsyn"},dispatcherTypes={DispatcherType.REQUEST,DispatcherType.ASYNC})
    

    测试过程:

    打开浏览器输入项目servlet地址:
    http://localhost:8080/ServletAsynFilter/ServletAsyn
    

    后台输出如图
    0
    浏览器输出如图
    1

    总结:

    输入servlet请求地址,出发过滤器,过滤器方法开始执行,然后servlet的dopost方法开始执行,于是,创建了内部类的一个异步线程。在线程还没有完成的时候,servlet继续往下执行。最后,线程的任务完成返回浏览器页面。

    下面是代码:
    ServletAsyn.java

     package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.AsyncContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * autor:xanwidtf@foxmail.com
     */
    /**
     * Servlet implementation class ServletAsyn
     */
    @WebServlet(name = "ServletAsyn", urlPatterns = "/ServletAsyn", asyncSupported = true)
    public class ServletAsyn extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        /**
         * @see HttpServlet#HttpServlet()
         */
        public ServletAsyn() {
            super();
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            //response.getWriter().append("Served at: ").append(request.getContextPath());
    
            System.out.println("Servlet执行开始时间:"+new Date());
              response.setCharacterEncoding("utf-8");
              response.setContentType("text/html;charset=utf-8");
              PrintWriter out = response.getWriter();
              Date date = new Date(System.currentTimeMillis());
              SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
              out.print("<h1>");
              out.println("Servlet  begin --" + sdf.format(date) + "<br>");// 响应输出到客户端
              out.print("</h1>");
              out.print("<hr>");
    
            /*
             * 体现异步思想,Servlet执行结束,而异步的线程仍然在继续跑
             */
            AsyncContext context=request.startAsync();
            new Thread(new Executor(context)).start(); //new Thread 传递AsyncContext对象   并且start
            System.out.println("Servlet执行结束时间:"+new Date());
        }
    
        //内部类实现线程
        public class Executor implements Runnable{
            private AsyncContext context;
            public Executor(AsyncContext context){
                this.context=context;
            }
    
            @Override
            public void run() {
                //执行相关复杂业务
                try {
                    Thread.sleep(1000*3);
                    context.getRequest();
                    context.getResponse();
                     ServletResponse response = context.getResponse();
                        PrintWriter out = response.getWriter();
                        Date date = new Date(System.currentTimeMillis());
                        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    
                        out.print("<h1>");
                        out.println("Thread worker finished --"+ sdf.format(date));// 响应输出到客户端
                        out.print("</h1><hr>");
                        out.flush();
                        System.out.println("业务完成时间:"+new Date());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    

    Filter.java

    package Filter;
    
    import java.io.IOException;
    
    import javax.servlet.DispatcherType;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    
    @WebFilter(filterName="AsynFilter",asyncSupported=true,value={"/ServletAsyn"},dispatcherTypes={DispatcherType.REQUEST,DispatcherType.ASYNC})
    public class AsynFilter implements Filter {
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
                throws IOException, ServletException {
            System.out.println("Start.....AsynFilter");
            arg2.doFilter(arg0, arg1);
            System.out.println("End....AsynFilter");
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }
    
  • 相关阅读:
    Coolpy程序安装教程
    Coolpy使用注意事项以及常见问题解决办法(持续更新中)
    自备百度地图API密钥 解决Cooply“地图API未授权”问题
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之八
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之七
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之六
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之六
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之五
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之四
    如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之三
  • 原文地址:https://www.cnblogs.com/famine/p/9124725.html
Copyright © 2020-2023  润新知