Package org.springframework.web.context.request.async

# Class WebAsyncManager

java.lang.Object
org.springframework.web.context.request.async.WebAsyncManager

public final class WebAsyncManager extends Object
The central class for managing asynchronous request processing, mainly intended as an SPI and not typically used directly by application classes.

An async scenario starts with request processing as usual in a thread (T1). Concurrent request handling can be initiated by calling `startCallableProcessing` or `startDeferredResultProcessing`, both of which produce a result in a separate thread (T2). The result is saved and the request dispatched to the container, to resume processing with the saved result in a third thread (T3). Within the dispatched thread (T3), the saved result can be accessed via `getConcurrentResult()` or its presence detected via `hasConcurrentResult()`.

Since:
  3.2
Author:
  Rossen Stoyanchev, Juergen Hoeller, Sam Brannen
See Also:
  - `AsyncWebRequestInterceptor`
  - `org.springframework.web.servlet.AsyncHandlerInterceptor`
  - `OncePerRequestFilter.shouldNotFilterAsyncDispatch()`
  - `OncePerRequestFilter.isAsyncDispatch(jakarta.servlet.http.HttpServletRequest)`

## Method Summary

Modifier and Type
Method
Description
`void`
`clearConcurrentResult()`
Clear concurrentResult and concurrentResultContext.
`AsyncWebRequest`
`getAsyncWebRequest()`
Return the current `AsyncWebRequest`.
`CallableProcessingInterceptor`
`getCallableInterceptor(Object key)`
Get the `CallableProcessingInterceptor` registered under the given key.
`Object`
`getConcurrentResult()`
Get the result from concurrent handling.
`Object[]`
`getConcurrentResultContext()`
Get the additional processing context saved at the start of concurrent handling.
`DeferredResultProcessingInterceptor`
`getDeferredResultInterceptor(Object key)`
Get the `DeferredResultProcessingInterceptor` registered under the given key.
`boolean`
`hasConcurrentResult()`
Return whether a result value exists as a result of concurrent handling.
`boolean`
`isConcurrentHandlingStarted()`
Return whether the selected handler for the current request chose to handle the request asynchronously.
`boolean`
`isMultipartRequestParsed()`
Return `true` if this `WebAsyncManager` was previously marked as wrapping a multipart async request, `false` otherwise.
`void`
`registerCallableInterceptor(Object key, CallableProcessingInterceptor interceptor)`
Register a `CallableProcessingInterceptor` under the given key.
`void`
`registerCallableInterceptors(CallableProcessingInterceptor... interceptors)`
Register a `CallableProcessingInterceptor` without a key.
`void`
`registerDeferredResultInterceptor(Object key, DeferredResultProcessingInterceptor interceptor)`
Register a `DeferredResultProcessingInterceptor` under the given key.
`void`
`registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors)`
Register one or more `DeferredResultProcessingInterceptors` without a specified key.
`void`
`setAsyncWebRequest(AsyncWebRequest asyncWebRequest)`
Configure the `AsyncWebRequest` to use.
`void`
`setMultipartRequestParsed(boolean isMultipart)`
Mark the `WebAsyncManager` as wrapping a multipart async request.
`void`
`setTaskExecutor(org.springframework.core.task.AsyncTaskExecutor taskExecutor)`
Configure an AsyncTaskExecutor for use with concurrent processing via `startCallableProcessing(Callable, Object...)`.
`void`
`startCallableProcessing(Callable<?> callable, Object... processingContext)`
Start concurrent request processing and execute the given task with an `AsyncTaskExecutor`.
`void`
`startCallableProcessing(WebAsyncTask<?> webAsyncTask, Object... processingContext)`
Use the given `WebAsyncTask` to configure the task executor as well as the timeout value of the `AsyncWebRequest` before delegating to `startCallableProcessing(Callable, Object...)`.
`void`
`startDeferredResultProcessing(DeferredResult<?> deferredResult, Object... processingContext)`
Start concurrent request processing and initialize the given `DeferredResult` with a `DeferredResult.DeferredResultHandler` that saves the result and dispatches the request to resume processing of that result.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Method Details

### setAsyncWebRequest

public void setAsyncWebRequest(AsyncWebRequest asyncWebRequest)
Configure the `AsyncWebRequest` to use. This property may be set more than once during a single request to accurately reflect the current state of the request (for example, following a forward, request/response wrapping, etc). However, it should not be set while concurrent handling is in progress, i.e. while `isConcurrentHandlingStarted()` is `true`.

Parameters:
  `asyncWebRequest` - the web request to use

### getAsyncWebRequest

@Nullable public AsyncWebRequest getAsyncWebRequest()
Return the current `AsyncWebRequest`.

Since:
  5.3.33

### setTaskExecutor

public void setTaskExecutor(org.springframework.core.task.AsyncTaskExecutor taskExecutor)
Configure an AsyncTaskExecutor for use with concurrent processing via `startCallableProcessing(Callable, Object...)`.

By default a `SimpleAsyncTaskExecutor` instance is used.

### isConcurrentHandlingStarted

public boolean isConcurrentHandlingStarted()
Return whether the selected handler for the current request chose to handle the request asynchronously. A return value of "true" indicates concurrent handling is under way and the response will remain open. A return value of "false" means concurrent handling was either not started or possibly that it has completed and the request was dispatched for further processing of the concurrent result.

### hasConcurrentResult

public boolean hasConcurrentResult()
Return whether a result value exists as a result of concurrent handling.

### getConcurrentResult

@Nullable public Object getConcurrentResult()
Get the result from concurrent handling.

Returns:
  an Object, possibly an `Exception` or `Throwable` if concurrent handling raised one
See Also:
  - `clearConcurrentResult()`

### getConcurrentResultContext

@Nullable public Object[] getConcurrentResultContext()
Get the additional processing context saved at the start of concurrent handling.

See Also:
  - `clearConcurrentResult()`

### getCallableInterceptor

@Nullable public CallableProcessingInterceptor getCallableInterceptor(Object key)
Get the `CallableProcessingInterceptor` registered under the given key.

Parameters:
  `key` - the key
Returns:
  the interceptor registered under that key, or `null` if none

### getDeferredResultInterceptor

@Nullable public DeferredResultProcessingInterceptor getDeferredResultInterceptor(Object key)
Get the `DeferredResultProcessingInterceptor` registered under the given key.

Parameters:
  `key` - the key
Returns:
  the interceptor registered under that key, or `null` if none

### registerCallableInterceptor

public void registerCallableInterceptor(Object key, CallableProcessingInterceptor interceptor)
Register a `CallableProcessingInterceptor` under the given key.

Parameters:
  `key` - the key
  `interceptor` - the interceptor to register

### registerCallableInterceptors

public void registerCallableInterceptors(CallableProcessingInterceptor... interceptors)
Register a `CallableProcessingInterceptor` without a key. The key is derived from the class name and hash code.

Parameters:
  `interceptors` - one or more interceptors to register

### registerDeferredResultInterceptor

public void registerDeferredResultInterceptor(Object key, DeferredResultProcessingInterceptor interceptor)
Register a `DeferredResultProcessingInterceptor` under the given key.

Parameters:
  `key` - the key
  `interceptor` - the interceptor to register

### registerDeferredResultInterceptors

public void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors)
Register one or more `DeferredResultProcessingInterceptors` without a specified key. The default key is derived from the interceptor class name and hash code.

Parameters:
  `interceptors` - one or more interceptors to register

### setMultipartRequestParsed

public void setMultipartRequestParsed(boolean isMultipart)
Mark the `WebAsyncManager` as wrapping a multipart async request.

Since:
  6.1.12

### isMultipartRequestParsed

public boolean isMultipartRequestParsed()
Return `true` if this `WebAsyncManager` was previously marked as wrapping a multipart async request, `false` otherwise.

Since:
  6.1.12

### clearConcurrentResult

public void clearConcurrentResult()
Clear concurrentResult and concurrentResultContext.

### startCallableProcessing

public void startCallableProcessing(Callable<?> callable, Object... processingContext) throws Exception
Start concurrent request processing and execute the given task with an `AsyncTaskExecutor`. The result from the task execution is saved and the request dispatched in order to resume processing of that result. If the task raises an Exception then the saved result will be the raised Exception.

Parameters:
  `callable` - a unit of work to be executed asynchronously
  `processingContext` - additional context to save that can be accessed via `getConcurrentResultContext()`
Throws:
  `Exception` - if concurrent processing failed to start
See Also:
  - `getConcurrentResult()`
  - `getConcurrentResultContext()`

### startCallableProcessing

public void startCallableProcessing(WebAsyncTask<?> webAsyncTask, Object... processingContext) throws Exception
Use the given `WebAsyncTask` to configure the task executor as well as the timeout value of the `AsyncWebRequest` before delegating to `startCallableProcessing(Callable, Object...)`.

Parameters:
  `webAsyncTask` - a WebAsyncTask containing the target `Callable`
  `processingContext` - additional context to save that can be accessed via `getConcurrentResultContext()`
Throws:
  `Exception` - if concurrent processing failed to start

### startDeferredResultProcessing

public void startDeferredResultProcessing(DeferredResult<?> deferredResult, Object... processingContext) throws Exception
Start concurrent request processing and initialize the given `DeferredResult` with a `DeferredResult.DeferredResultHandler` that saves the result and dispatches the request to resume processing of that result. The `AsyncWebRequest` is also updated with a completion handler that expires the `DeferredResult` and a timeout handler assuming the `DeferredResult` has a default timeout result.

Parameters:
  `deferredResult` - the DeferredResult instance to initialize
  `processingContext` - additional context to save that can be accessed via `getConcurrentResultContext()`
Throws:
  `Exception` - if concurrent processing failed to start
See Also:
  - `getConcurrentResult()`
  - `getConcurrentResultContext()`