Servlet异步

原理

经常有这样一类需求,客户端发送一个请求,但服务端什么时候有数据返回不知道,这个时候可以考虑用异步来实现,servlet从3.0版本后就支持这个功能了,主要通过AsyncContext来实现的,在springboot里写了一个demo实践一下。

完整代码

@WebServlet(asyncSupported = true, urlPatterns = {"/getData"})
public class AysnServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setHeader("Cache-Control", "private");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Connection", "Keep-Alive");
        response.setHeader("Proxy-Connection", "Keep-Alive");
        response.setContentType("text/html;charset=UTF-8");

        System.out.println("response === >" +response);


        final AsyncContext context = request.startAsync(request, response);
        context.setTimeout(30 * 000);

        System.out.println("context.response ====> " + context.getResponse());

        context.start(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(20000); //模拟某些处理的花费时间
                    System.out.println("hello aysncontext");
                    PrintWriter writer = new PrintWriter(context.getResponse().getWriter(),true);
                    writer.write("Hello, AsyncContext!");
                    writer.flush();
                    context.complete(); //log输出onComplete...
                } catch (IllegalStateException e1) {
                    System.out.println("Received IllegalStateException, maybe timeout");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        System.out.println("first write data");
        PrintWriter out = response.getWriter();
        out.println("first write data\n");
        out.flush();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doGet(req, resp);
    }
}


/**
 * Created by gaofla on 2018/3/15.
 */
@SpringBootApplication
public class Application {
    public static void main(String args[]) {
        SpringApplication.run(Application.class, args);
    }


    @Bean
    public ServletRegistrationBean testServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new AysnServlet());
        registration.addUrlMappings("/getData");
        return registration;
    }

}