• servlet异步请求与spring mvc异步请求


    servlet异步请求

    import java.io.IOException;
    
    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;
    
    @WebServlet(value="/async",asyncSupported=true)
    public class HelloAsyncServlet extends HttpServlet {
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1、支持异步处理asyncSupported=true
            //2、开启异步模式
            System.out.println("主线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
            AsyncContext startAsync = req.startAsync();
            
            //3、业务逻辑进行异步处理;开始异步处理
            startAsync.start(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("副线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
                        sayHello();
                        startAsync.complete();
                        //获取到异步上下文
                        AsyncContext asyncContext = req.getAsyncContext();
                        //4、获取响应
                        ServletResponse response = asyncContext.getResponse();
                        response.getWriter().write("hello async...");
                        System.out.println("副线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    } catch (Exception e) {
                    }
                }
            });        
            System.out.println("主线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
        }
    
        public void sayHello() throws Exception{
            System.out.println(Thread.currentThread()+" processing...");
            Thread.sleep(3000);
        }
    }

    spring mvc异步请求

    import java.util.UUID;
    import java.util.concurrent.Callable;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.context.request.async.DeferredResult;
    
    import com.atguigu.service.DeferredResultQueue;
    
    
    @Controller
    public class AsyncController {
        
        
        @ResponseBody
        @RequestMapping("/createOrder")
        public DeferredResult<Object> createOrder(){
            DeferredResult<Object> deferredResult = new DeferredResult<>((long)3000, "create fail...");
                
            DeferredResultQueue.save(deferredResult);
            
            return deferredResult;
        }
        
        
        @ResponseBody
        @RequestMapping("/create")
        public String create(){
            //创建订单
            String order = UUID.randomUUID().toString();
            DeferredResult<Object> deferredResult = DeferredResultQueue.get();
            deferredResult.setResult(order);
            return "success===>"+order;
        }
        
        /**
         * 1、控制器返回Callable
         * 2、Spring异步处理,将Callable 提交到 TaskExecutor 使用一个隔离的线程进行执行
         * 3、DispatcherServlet和所有的Filter退出web容器的线程,但是response 保持打开状态;
         * 4、Callable返回结果,SpringMVC将请求重新派发给容器,恢复之前的处理;
         * 5、根据Callable返回的结果。SpringMVC继续进行视图渲染流程等(从收请求-视图渲染)。
         * 
         * preHandle.../springmvc-annotation/async01
            主线程开始...Thread[http-bio-8081-exec-3,5,main]==>1513932494700
            主线程结束...Thread[http-bio-8081-exec-3,5,main]==>1513932494700
            =========DispatcherServlet及所有的Filter退出线程============================
            
            ================等待Callable执行==========
            副线程开始...Thread[MvcAsync1,5,main]==>1513932494707
            副线程开始...Thread[MvcAsync1,5,main]==>1513932496708
            ================Callable执行完成==========
            
            ================再次收到之前重发过来的请求========
            preHandle.../springmvc-annotation/async01
            postHandle...(Callable的之前的返回值就是目标方法的返回值)
            afterCompletion...
            
            异步的拦截器:
                1)、原生API的AsyncListener
                2)、SpringMVC:实现AsyncHandlerInterceptor;
         * @return
         */
        @ResponseBody
        @RequestMapping("/async01")
        public Callable<String> async01(){
            System.out.println("主线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
            
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println("副线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    Thread.sleep(2000);
                    System.out.println("副线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    return "Callable<String> async01()";
                }
            };
            
            System.out.println("主线程结束..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
            return callable;
        }
    
    }

    DeferredResultQueue 

    import java.util.Queue;
    import java.util.concurrent.ConcurrentLinkedQueue;
    
    import org.springframework.web.context.request.async.DeferredResult;
    
    public class DeferredResultQueue {
        
        private static Queue<DeferredResult<Object>> queue = new ConcurrentLinkedQueue<DeferredResult<Object>>();
        
        public static void save(DeferredResult<Object> deferredResult){
            queue.add(deferredResult);
        }
        
        public static DeferredResult<Object> get( ){
            return queue.poll();
        }
    
    }
  • 相关阅读:
    【转载】动态加载wpf控件主题样式资源
    paip.批处理清理java项目冗余jar的方法
    paip.java OutOfMemoryError 解决方法o33
    paip.java win程序迁移linux的最佳实践
    paip.java c# .net php python调用c++ c dll so windows api 总结
    paip.提高效率微信 手机app快速开发平台—微网络撬动大市场
    paip.Log4j配置不起作用的解决
    paip.获取地理位置根据Ip
    paip.java 开发中web server的选择jboss resin tomcat比较..
    paip.提升安全性Des加密 java php python的实现总结
  • 原文地址:https://www.cnblogs.com/huangzhen22/p/13208516.html
Copyright © 2020-2023  润新知