Springmvc中的异步请求
例子
@Controller
public class HelloController {
@GetMapping(path = "/greeting")
public DeferredResult<String> hello(HttpServletResponse response) throws Exception {
DeferredResult<String> deferredResult = new DeferredResult<>();
executorService.submit(() -> perform(deferredResult));
return deferredResult;
}
private void perform(DeferredResult<String> dr) {
// some processing
dr.setResult("OK");
}
}
解释
DeferredResult
延期的结果;该方法返回一个 DeferredResult<String>对象,这是一个特殊的类型,用于支持异步请求处理。
DeferredResult 是Spring MVC提供的一个工具类,用于实现基于Servlet 3.0异步支持的异步请求处理。当你返回一个 DeferredResult对象时,Spring MVC不会立即完成响应,而是会等待直到你调用 setResult或 setErrorResult方法来设置响应的结果。这允许你在后台线程中执行耗时的操作,而不会阻塞Servlet容器的主线程。
executorService
executorService是一个 ExecutorService实例,
例如:private final ExecutorService executorService = Executors.newSingleThreadExecutor();
推荐用线程池
请求流程
- 当一个HTTP GET请求到达
/greeting路径时,hello方法会被调用。 - 在
hello方法中,创建了一个新的DeferredResult<String>对象,并且将其提交给一个后台线程执行。这个后台线程是通过调用executorService.submit()来启动的,其中executorService是一个ExecutorService实例(尽管在提供的代码片段中并没有显示executorService的声明和初始化)。 - 后台线程执行
perform方法,该方法执行一些处理(这里没有具体说明),然后调用dr.setResult("OK")来设置异步响应的结果。 - 当
setResult方法被调用时,Spring MVC会恢复请求的处理,并将结果(在这里是字符串"OK")发送回客户端。
注意事项
DeferredResult对象必须在请求处理期间保持可达- 注意perform方法的异常处理和
DeferredResult对象的超时时间// 设置超时时间,例如30秒 deferredResult.setTimeout(30000L);
// 提交后台任务
executorService.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
perform(deferredResult);
} catch (Exception e) {
// 如果有异常,设置错误结果
deferredResult.setErrorResult("Error occurred: " + e.getMessage());
}
return null;
}
});
废话短说