Detail the processing of asynchronous requests by spring mvc


Asynchronous processing of requests is added in spring mvc3.2 and above, which is encapsulated on the basis of servlet3.

1. Modify web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
...
</web-app>

1.1. Declare version=“3.0” and web-app_3_0.xsd

1.2. Enable asynchronous support for servlet or filter Settings: < async-supported > true < /async-supported > , modify the web.xml application of WEB

<!-- spring mvc -->
<servlet>
<servlet-name>SpringMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>...</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>

2. Make controller class support async

2.1, return java. util. concurrent. Callable asynchronous processing to complete

package org.springframework.samples.mvc.async;

import java.util.concurrent.Callable;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.WebAsyncTask;

@Controller
@RequestMapping("/async/callable")
public class CallableController {
  @RequestMapping("/response-body")
  public @ResponseBody Callable<String> callable() {

    return new Callable<String>() {
      @Override
      public String call() throws Exception {
        Thread.sleep(2000);
        return "Callable result";
      }
    };
  }

  @RequestMapping("/view")
  public Callable<String> callableWithView(final Model model) {

    return new Callable<String>() {
      @Override
      public String call() throws Exception {
        Thread.sleep(2000);
        model.addAttribute("foo", "bar");
        model.addAttribute("fruit", "apple");
        return "views/html";
      }
    };
  }

  @RequestMapping("/exception")
  public @ResponseBody Callable<String> callableWithException(
      final @RequestParam(required=false, defaultValue="true") boolean handled) {

    return new Callable<String>() {
      @Override
      public String call() throws Exception {
        Thread.sleep(2000);
        if (handled) {
          // see handleException method further below
          throw new IllegalStateException("Callable error");
        }
        else {
          throw new IllegalArgumentException("Callable error");
        }
      }
    };
  }

  @RequestMapping("/custom-timeout-handling")
  public @ResponseBody WebAsyncTask<String> callableWithCustomTimeoutHandling() {

    Callable<String> callable = new Callable<String>() {
      @Override
      public String call() throws Exception {
        Thread.sleep(2000);
        return "Callable result";
      }
    };

    return new WebAsyncTask<String>(1000, callable);
  }

  @ExceptionHandler
  @ResponseBody
  public String handleException(IllegalStateException ex) {
    return "Handled exception: " + ex.getMessage();
  }

}

2.2, the asynchronous returns org. When processing is complete. springframework web. context. request. async. DeferredResult other threads, such as 1 or 1 AMQP JMS message, Redis notice, etc. :

@RequestMapping("/quotes")
@ResponseBody
public DeferredResult<String> quotes() {
 DeferredResult<String> deferredResult = new DeferredResult<String>();
 // Add deferredResult to a Queue or a Map...
 return deferredResult;
}

// In some other thread...
deferredResult.setResult(data);
// Remove deferredResult from the Queue or Map

3. Modification of spring configuration file

spring mvc’s dtd declaration must be greater than or equal to 3.2

<mvc:annotation-driven>
<!--  Instead of setting, use the default timeout  -->
  <mvc:async-support default-timeout="3000"/>
</mvc:annotation-driven>

Examples of actual use:

function deferred(){
  $.get('quotes.htm',function(data){
    console.log(data);
    deferred();// Each request completed , Again hair 1 Time request , Avoid client periodic refreshes to retrieve data
  });
}

The benefit of this is to avoid the performance problems caused by the long-term use of the web server connection pool, and to generate a non-web service thread to handle the call, increasing the throughput of the web server