美文网首页
Spring Boot 基于Servlet 的异步服务

Spring Boot 基于Servlet 的异步服务

作者: CallMe兵哥 | 来源:发表于2019-03-28 10:38 被阅读0次

    Servlet 3.0中支持异步的HTTP请求,本章基于Spring Boot 搭建一个基于Servlet 3.0异步HTTP服务,如果你对异步和同步还有疑问或者概念不清晰,请自行上网查阅相关资料。

    1. 在pom.xml中引入配置
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    1. 建立Service层接口
    public interface PiceaService {
        //无返回参数方法
        void task() throws Exception;
        //有返回参数方法
        String task2() throws Exception;
    }
    
    1. 建立Service层实现
      Service层接口与实现,跟其他正常同步请求一样,没有差别。
    @Service
    public class PiceaServiceImpl implements PiceaService {
    
        @Override
        public void task() throws Exception {
            System.out.println("------------------------在看貂蝉,不要打扰--------------");
            Thread.sleep(1000);
        }
    
        @Override
        public String task2 () throws Exception {
            int k = 1;
            System.out.println("------------------------在看鱼,不要打扰--------------");
            Thread.sleep(1000);
            return (String.valueOf(k));
        }
    }
    
    1. 最重要的一步,建立Contoller层方法
      在Contoller层,主要是利用了Servlet 3.0为异步处理提供的监听器,使用AsyncListener接口表示。此接口负责管理异步事件,它可以监控如下四种事件:
      1). 异步线程开始时,调用AsyncListener的onStartAsync(AsyncEvent event)方法;
      2). 异步线程出错时,调用AsyncListener的onError(AsyncEvent event)方法;
      3). 异步线程执行超时,则调用AsyncListener的onTimeout(AsyncEvent event)方法;
      4). 异步执行完毕时,调用AsyncListener的onComplete(AsyncEvent event)方法;
    @RestController
    public class PiceaServletContoller {
    
        @Autowired
        private PiceaService piceaService;
    
        @RequestMapping("/task")
        public void task(HttpServletRequest request,
                         HttpServletResponse response) throws Exception {
            piceaService.task();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("这个是无返回的处理方法");
        }
    
        @RequestMapping("/asyncTask")
        public void asyncTask(HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
            System.out.println("控制层线程:" + Thread.currentThread().getName());
            AsyncContext asyncContext = request.startAsync();
            asyncContext.addListener(new AsyncListener() {
                @Override
                public void onComplete(AsyncEvent asyncEvent) throws IOException {
                    // 异步执行完毕时
                    System.out.println("异步执行完毕");
                }
    
                @Override
                public void onTimeout(AsyncEvent asyncEvent) throws IOException {
                    //异步线程执行超时
                    System.out.println("异步线程执行超时");
                }
    
                @Override
                public void onError(AsyncEvent asyncEvent) throws IOException {
                    //异步线程出错时
                    System.out.println("异步线程出错");
                }
    
                @Override
                public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
                    //异步线程开始时
                    System.out.println("异步线程开始");
                }
            });
            asyncContext.setTimeout(3000);
            asyncContext.start(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("异步执行线程:" + Thread.currentThread().getName());
                        String str = piceaService.task2();
                        Thread.sleep(1000);
                        asyncContext.getResponse().setCharacterEncoding("UTF-8");
                        asyncContext.getResponse().setContentType("text/html;charset=UTF-8");
                        asyncContext.getResponse().getWriter().println("这是【异步】的请求返回: " +str);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                    //异步请求完成通知,所有任务完成了,才执行
                    asyncContext.complete();
                }
            });
        }
    }
    
    1. 测试结果及方法
      浏览器中分别访问http://localhost:2001/taskhttp://localhost:2001/asyncTask测试结果。
      在异步时,明显可以看到执行线程是不一样的。
      Spring-boot-async-servlet.png

    老板,欢迎下次再来!

    其它注意

    本文章样例:
    工程名:spring-boot-async-servlet
    GitHub:https://github.com/zzyjb/SpringBootLearning

    相关文章

      网友评论

          本文标题:Spring Boot 基于Servlet 的异步服务

          本文链接:https://www.haomeiwen.com/subject/sxifbqtx.html