1 /* 2 * Copyright 2002-2012 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.springframework.web.context.request.async; 17 18 import org.springframework.web.context.request.NativeWebRequest; 19 20 /** 21 * Intercepts concurrent request handling, where the concurrent result is 22 * obtained by waiting for a {@link DeferredResult} to be set from a thread 23 * chosen by the application (e.g. in response to some external event). 24 * 25 * <p>A {@code DeferredResultProcessingInterceptor} is invoked before the start 26 * of async processing, after the {@code DeferredResult} is set as well as on 27 * timeout, or or after completing for any reason including a timeout or network 28 * error. 29 * 30 * <p>As a general rule exceptions raised by interceptor methods will cause 31 * async processing to resume by dispatching back to the container and using 32 * the Exception instance as the concurrent result. Such exceptions will then 33 * be processed through the {@code HandlerExceptionResolver} mechanism. 34 * 35 * <p>The {@link #handleTimeout(NativeWebRequest, DeferredResult) afterTimeout} 36 * method can set the {@code DeferredResult} in order to resume processing. 37 * 38 * @author Rossen Stoyanchev 39 * @author Rob Winch 40 * @since 3.2 41 */ 42 public interface DeferredResultProcessingInterceptor { 43 44 /** 45 * Invoked immediately before the start of concurrent handling, in the same 46 * thread that started it. This method may be used to capture state just prior 47 * to the start of concurrent processing with the given {@code DeferredResult}. 48 * 49 * @param request the current request 50 * @param deferredResult the DeferredResult for the current request 51 * @throws Exception in case of errors 52 */ 53 <T> void beforeConcurrentHandling(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 54 55 /** 56 * Invoked immediately after the start of concurrent handling, in the same 57 * thread that started it. This method may be used to detect the start of 58 * concurrent processing with the given {@code DeferredResult}. 59 * 60 * <p>The {@code DeferredResult} may have already been set, for example at 61 * the time of its creation or by another thread. 62 * 63 * @param request the current request 64 * @param deferredResult the DeferredResult for the current request 65 * @throws Exception in case of errors 66 */ 67 <T> void preProcess(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 68 69 /** 70 * Invoked after a {@code DeferredResult} has been set, via 71 * {@link DeferredResult#setResult(Object)} or 72 * {@link DeferredResult#setErrorResult(Object)}, and is also ready to 73 * handle the concurrent result. 74 * 75 * <p>This method may also be invoked after a timeout when the 76 * {@code DeferredResult} was created with a constructor accepting a default 77 * timeout result. 78 * 79 * @param request the current request 80 * @param deferredResult the DeferredResult for the current request 81 * @param concurrentResult the result to which the {@code DeferredResult} 82 * @throws Exception in case of errors 83 */ 84 <T> void postProcess(NativeWebRequest request, DeferredResult<T> deferredResult, Object concurrentResult) throws Exception; 85 86 /** 87 * Invoked from a container thread when an async request times out before 88 * the {@code DeferredResult} has been set. Implementations may invoke 89 * {@link DeferredResult#setResult(Object) setResult} or 90 * {@link DeferredResult#setErrorResult(Object) setErrorResult} to resume processing. 91 * 92 * @param request the current request 93 * @param deferredResult the DeferredResult for the current request; if the 94 * {@code DeferredResult} is set, then concurrent processing is resumed and 95 * subsequent interceptors are not invoked 96 * @return {@code true} if processing should continue, or {@code false} if 97 * other interceptors should not be invoked 98 * @throws Exception in case of errors 99 */ 100 <T> boolean handleTimeout(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 101 102 /** 103 * Invoked from a container thread when an async request completed for any 104 * reason including timeout and network error. This method is useful for 105 * detecting that a {@code DeferredResult} instance is no longer usable. 106 * 107 * @param request the current request 108 * @param deferredResult the DeferredResult for the current request 109 * @throws Exception in case of errors 110 */ 111 <T> void afterCompletion(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 112 113 }