1
1
/*
2
- * Copyright 2002-2013 the original author or authors.
2
+ * Copyright 2002-2014 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
+
16
17
package org .springframework .web .context .request .async ;
17
18
18
19
import java .util .ArrayList ;
19
20
import java .util .LinkedHashMap ;
20
21
import java .util .List ;
21
22
import java .util .Map ;
22
23
import java .util .concurrent .Callable ;
23
-
24
24
import javax .servlet .http .HttpServletRequest ;
25
25
26
26
import org .apache .commons .logging .Log ;
27
27
import org .apache .commons .logging .LogFactory ;
28
+
28
29
import org .springframework .core .task .AsyncTaskExecutor ;
29
30
import org .springframework .core .task .SimpleAsyncTaskExecutor ;
30
31
import org .springframework .util .Assert ;
48
49
*
49
50
* @author Rossen Stoyanchev
50
51
* @since 3.2
51
- *
52
52
* @see org.springframework.web.context.request.AsyncWebRequestInterceptor
53
53
* @see org.springframework.web.servlet.AsyncHandlerInterceptor
54
54
* @see org.springframework.web.filter.OncePerRequestFilter#shouldNotFilterAsyncDispatch
@@ -85,21 +85,21 @@ public final class WebAsyncManager {
85
85
86
86
87
87
/**
88
- * Package private constructor.
88
+ * Package- private constructor.
89
89
* @see WebAsyncUtils#getAsyncManager(javax.servlet.ServletRequest)
90
90
* @see WebAsyncUtils#getAsyncManager(org.springframework.web.context.request.WebRequest)
91
91
*/
92
92
WebAsyncManager () {
93
93
}
94
94
95
+
95
96
/**
96
97
* Configure the {@link AsyncWebRequest} to use. This property may be set
97
98
* more than once during a single request to accurately reflect the current
98
99
* state of the request (e.g. following a forward, request/response
99
100
* wrapping, etc). However, it should not be set while concurrent handling
100
101
* is in progress, i.e. while {@link #isConcurrentHandlingStarted()} is
101
102
* {@code true}.
102
- *
103
103
* @param asyncWebRequest the web request to use
104
104
*/
105
105
public void setAsyncWebRequest (final AsyncWebRequest asyncWebRequest ) {
@@ -143,7 +143,6 @@ public boolean hasConcurrentResult() {
143
143
144
144
/**
145
145
* Provides access to the result from concurrent handling.
146
- *
147
146
* @return an Object, possibly an {@code Exception} or {@code Throwable} if
148
147
* concurrent handling raised one.
149
148
* @see #clearConcurrentResult()
@@ -155,7 +154,6 @@ public Object getConcurrentResult() {
155
154
/**
156
155
* Provides access to additional processing context saved at the start of
157
156
* concurrent handling.
158
- *
159
157
* @see #clearConcurrentResult()
160
158
*/
161
159
public Object [] getConcurrentResultContext () {
@@ -216,14 +214,14 @@ public void registerDeferredResultInterceptor(Object key, DeferredResultProcessi
216
214
}
217
215
218
216
/**
219
- * Register a {@link DeferredResultProcessingInterceptor} without a key.
220
- * The key is derived from the class name and hashcode .
217
+ * Register one or more {@link DeferredResultProcessingInterceptor}s without a specified key.
218
+ * The default key is derived from the interceptor class name and hash code .
221
219
* @param interceptors one or more interceptors to register
222
220
*/
223
221
public void registerDeferredResultInterceptors (DeferredResultProcessingInterceptor ... interceptors ) {
224
222
Assert .notNull (interceptors , "A DeferredResultProcessingInterceptor is required" );
225
223
for (DeferredResultProcessingInterceptor interceptor : interceptors ) {
226
- String key = interceptors .getClass ().getName () + ":" + interceptors .hashCode ();
224
+ String key = interceptor .getClass ().getName () + ":" + interceptor .hashCode ();
227
225
this .deferredResultInterceptors .put (key , interceptor );
228
226
}
229
227
}
@@ -243,17 +241,15 @@ public void clearConcurrentResult() {
243
241
* from the task execution is saved and the request dispatched in order to
244
242
* resume processing of that result. If the task raises an Exception then
245
243
* the saved result will be the raised Exception.
246
- *
247
244
* @param callable a unit of work to be executed asynchronously
248
245
* @param processingContext additional context to save that can be accessed
249
246
* via {@link #getConcurrentResultContext()}
250
- * @throws Exception If concurrent processing failed to start
251
- *
247
+ * @throws Exception if concurrent processing failed to start
252
248
* @see #getConcurrentResult()
253
249
* @see #getConcurrentResultContext()
254
250
*/
255
- @ SuppressWarnings ({"unchecked" })
256
- public void startCallableProcessing (final Callable <?> callable , Object ... processingContext ) throws Exception {
251
+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
252
+ public void startCallableProcessing (Callable <?> callable , Object ... processingContext ) throws Exception {
257
253
Assert .notNull (callable , "Callable must not be null" );
258
254
startCallableProcessing (new WebAsyncTask (callable ), processingContext );
259
255
}
@@ -262,11 +258,10 @@ public void startCallableProcessing(final Callable<?> callable, Object... proces
262
258
* Use the given {@link WebAsyncTask} to configure the task executor as well as
263
259
* the timeout value of the {@code AsyncWebRequest} before delegating to
264
260
* {@link #startCallableProcessing(Callable, Object...)}.
265
- *
266
261
* @param webAsyncTask a WebAsyncTask containing the target {@code Callable}
267
262
* @param processingContext additional context to save that can be accessed
268
263
* via {@link #getConcurrentResultContext()}
269
- * @throws Exception If concurrent processing failed to start
264
+ * @throws Exception if concurrent processing failed to start
270
265
*/
271
266
public void startCallableProcessing (final WebAsyncTask <?> webAsyncTask , Object ... processingContext ) throws Exception {
272
267
Assert .notNull (webAsyncTask , "WebAsyncTask must not be null" );
@@ -306,8 +301,7 @@ public void run() {
306
301
}
307
302
});
308
303
309
- interceptorChain .applyBeforeConcurrentHandling (asyncWebRequest , callable );
310
-
304
+ interceptorChain .applyBeforeConcurrentHandling (this .asyncWebRequest , callable );
311
305
startAsyncProcessing (processingContext );
312
306
313
307
this .taskExecutor .submit (new Runnable () {
@@ -317,8 +311,8 @@ public void run() {
317
311
interceptorChain .applyPreProcess (asyncWebRequest , callable );
318
312
result = callable .call ();
319
313
}
320
- catch (Throwable t ) {
321
- result = t ;
314
+ catch (Throwable ex ) {
315
+ result = ex ;
322
316
}
323
317
finally {
324
318
result = interceptorChain .applyPostProcess (asyncWebRequest , callable , result );
@@ -333,18 +327,20 @@ private void setConcurrentResultAndDispatch(Object result) {
333
327
if (hasConcurrentResult ()) {
334
328
return ;
335
329
}
336
- concurrentResult = result ;
330
+ this . concurrentResult = result ;
337
331
}
338
332
339
- if (asyncWebRequest .isAsyncComplete ()) {
333
+ if (this . asyncWebRequest .isAsyncComplete ()) {
340
334
logger .error ("Could not complete async processing due to timeout or network error" );
341
335
return ;
342
336
}
343
337
344
- logger .debug ("Concurrent result value [" + concurrentResult + "]" );
345
- logger .debug ("Dispatching request to resume processing" );
338
+ if (logger .isDebugEnabled ()) {
339
+ logger .debug ("Concurrent result value [" + this .concurrentResult +
340
+ "] - dispatching request to resume processing" );
341
+ }
346
342
347
- asyncWebRequest .dispatch ();
343
+ this . asyncWebRequest .dispatch ();
348
344
}
349
345
350
346
/**
@@ -354,12 +350,10 @@ private void setConcurrentResultAndDispatch(Object result) {
354
350
* result. The {@code AsyncWebRequest} is also updated with a completion
355
351
* handler that expires the {@code DeferredResult} and a timeout handler
356
352
* assuming the {@code DeferredResult} has a default timeout result.
357
- *
358
353
* @param deferredResult the DeferredResult instance to initialize
359
354
* @param processingContext additional context to save that can be accessed
360
355
* via {@link #getConcurrentResultContext()}
361
- * @throws Exception If concurrent processing failed to start
362
- *
356
+ * @throws Exception if concurrent processing failed to start
363
357
* @see #getConcurrentResult()
364
358
* @see #getConcurrentResultContext()
365
359
*/
@@ -386,8 +380,8 @@ public void run() {
386
380
try {
387
381
interceptorChain .triggerAfterTimeout (asyncWebRequest , deferredResult );
388
382
}
389
- catch (Throwable t ) {
390
- setConcurrentResultAndDispatch (t );
383
+ catch (Throwable ex ) {
384
+ setConcurrentResultAndDispatch (ex );
391
385
}
392
386
}
393
387
});
@@ -398,8 +392,7 @@ public void run() {
398
392
}
399
393
});
400
394
401
- interceptorChain .applyBeforeConcurrentHandling (asyncWebRequest , deferredResult );
402
-
395
+ interceptorChain .applyBeforeConcurrentHandling (this .asyncWebRequest , deferredResult );
403
396
startAsyncProcessing (processingContext );
404
397
405
398
try {
@@ -411,16 +404,14 @@ public void handleResult(Object result) {
411
404
}
412
405
});
413
406
}
414
- catch (Throwable t ) {
415
- setConcurrentResultAndDispatch (t );
407
+ catch (Throwable ex ) {
408
+ setConcurrentResultAndDispatch (ex );
416
409
}
417
410
}
418
411
419
412
private void startAsyncProcessing (Object [] processingContext ) {
420
-
421
413
clearConcurrentResult ();
422
414
this .concurrentResultContext = processingContext ;
423
-
424
415
this .asyncWebRequest .startAsync ();
425
416
426
417
if (logger .isDebugEnabled ()) {
0 commit comments