Fix issue in Callable processing interceptor chain

This commit is contained in:
Rossen Stoyanchev
2012-11-26 16:04:17 -05:00
parent 79edf627db
commit 5cb1930550
4 changed files with 43 additions and 6 deletions

View File

@@ -49,15 +49,22 @@ class CallableInterceptorChain {
}
public Object applyPostProcess(NativeWebRequest request, Callable<?> task, Object concurrentResult) {
Throwable exceptionResult = null;
for (int i = this.preProcessIndex; i >= 0; i--) {
try {
this.interceptors.get(i).postProcess(request, task, concurrentResult);
}
catch (Throwable t) {
return t;
// Save the first exception but invoke all interceptors
if (exceptionResult != null) {
logger.error("postProcess error", t);
}
else {
exceptionResult = t;
}
}
}
return concurrentResult;
return (exceptionResult != null) ? exceptionResult : concurrentResult;
}
public Object triggerAfterTimeout(NativeWebRequest request, Callable<?> task) {

View File

@@ -197,7 +197,7 @@ public final class WebAsyncManager {
* The key is derived from the class name and hashcode.
* @param interceptor the interceptor to register
*/
public void registerCallableInterceptor(CallableProcessingInterceptor... interceptors) {
public void registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {
Assert.notNull(interceptors, "A CallableProcessingInterceptor is required");
for (CallableProcessingInterceptor interceptor : interceptors) {
String key = interceptor.getClass().getName() + ":" + interceptor.hashCode();
@@ -222,7 +222,7 @@ public final class WebAsyncManager {
* @param key the key
* @param interceptors the interceptor to register
*/
public void registerDeferredResultInterceptor(DeferredResultProcessingInterceptor... interceptors) {
public void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {
Assert.notNull(interceptors, "A DeferredResultProcessingInterceptor is required");
for (DeferredResultProcessingInterceptor interceptor : interceptors) {
String key = interceptors.getClass().getName() + ":" + interceptors.hashCode();

View File

@@ -200,6 +200,36 @@ public class WebAsyncManagerTests {
verify(interceptor, this.asyncWebRequest);
}
@Test
public void startCallableProcessingPostProcessContinueAfterException() throws Exception {
Callable<Object> task = new StubCallable(21);
Exception exception = new Exception();
CallableProcessingInterceptor interceptor1 = createMock(CallableProcessingInterceptor.class);
interceptor1.preProcess(this.asyncWebRequest, task);
interceptor1.postProcess(this.asyncWebRequest, task, 21);
replay(interceptor1);
CallableProcessingInterceptor interceptor2 = createMock(CallableProcessingInterceptor.class);
interceptor2.preProcess(this.asyncWebRequest, task);
interceptor2.postProcess(this.asyncWebRequest, task, 21);
expectLastCall().andThrow(exception);
replay(interceptor2);
setupDefaultAsyncScenario();
this.asyncManager.registerCallableInterceptors(interceptor1, interceptor2);
this.asyncManager.startCallableProcessing(task);
assertTrue(this.asyncManager.hasConcurrentResult());
assertEquals(exception, this.asyncManager.getConcurrentResult());
verify(interceptor1);
verify(interceptor2);
verify(this.asyncWebRequest);
}
@Test
public void startCallableProcessingWithAsyncTask() {

View File

@@ -728,8 +728,8 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptor(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptor(this.deferredResultInterceptors);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();