正文
目前,我们编写的代码基本上都是同步请求的,我们每次请求,都会占用过客户端的一个资源,一个链接,导致连接数减少。如何进行异步处理,那么我们处理的速度会大大的增加。
方法一:servlet3.0后,我们的servlet支持了异步请求的方式来执行我们的业务逻辑。
通过
request.startAsync(request, response)
来将同步请求转为异步,该方法返回一个AsyncContext 对象,在A中将该对象保存起来,等B的响应到来的时候,就可以利用该对象来拿到response,向A反馈响应了xml配置:<async-supported>true</async-supported>
注解配置:@WebServlet(urlPatterns = { "/app/*" }, asyncSupported = true)
异步请求的过程:
@Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request=(HttpServletRequest)req; final HttpServletResponse response=(HttpServletResponse)res; AsyncContext asyncContext = request.getAsyncContext(); // 开启另一个线程 asyncContext.start(new Runnable() { @Override public void run() { try { // 返回数据 response.getWriter().print("执行成功"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); }
方法二:Spring-mvc的方式
在我们Spring的官方文档中,我们可以知道,Spring对于一步的请求也是支持的,文档地址:
Spring MVC has an extensive integration with Servlet 3.0 asynchronous request processing:
DeferredResult
andCallable
return values in controller methods and provide basic support for a single asynchronous return value.- Controllers can stream multiple values, including SSE and raw data.
- Controllers can use reactive clients and return reactive types for response handling.
要想实现,异步请求,我们要在基本的servlet上面配置支持异步请求:
In
web.xml
configuration, you can add<async-supported>true</async-supported>
to theDispatcherServlet
and toFilter
declarations and add<dispatcher>ASYNC</dispatcher>
to filter mappings.
下面介绍2种最常用的:
- 使用 DeferredResult 来完成异步请求:
@GetMapping("/quotes") @ResponseBody public DeferredResult<String> quotes() { DeferredResult<String> deferredResult = new DeferredResult<String>(); // Save the deferredResult somewhere.. return deferredResult; } // From some other thread... deferredResult.setResult(result);
从上面我们可以知道:处理请求的是一个线程,业务逻辑是另一个线程。
- 使用Callable 来完成异步请求:
@PostMapping public Callable<String> processUpload(final MultipartFile file) { return new Callable<String>() { public String call() throws Exception { // ... return "someView"; } }; }
这样我们就可以实现请求的异步请求。