原理
经常有这样一类需求,客户端发送一个请求,但服务端什么时候有数据返回不知道,这个时候可以考虑用异步来实现,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;
}
}