001/* 002 * Copyright 2002-2015 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.context.request.async; 018 019import org.springframework.web.context.request.NativeWebRequest; 020 021/** 022 * Intercepts concurrent request handling, where the concurrent result is 023 * obtained by waiting for a {@link DeferredResult} to be set from a thread 024 * chosen by the application (e.g. in response to some external event). 025 * 026 * <p>A {@code DeferredResultProcessingInterceptor} is invoked before the start 027 * of async processing, after the {@code DeferredResult} is set as well as on 028 * timeout, or after completing for any reason including a timeout or network 029 * error. 030 * 031 * <p>As a general rule exceptions raised by interceptor methods will cause 032 * async processing to resume by dispatching back to the container and using 033 * the Exception instance as the concurrent result. Such exceptions will then 034 * be processed through the {@code HandlerExceptionResolver} mechanism. 035 * 036 * <p>The {@link #handleTimeout(NativeWebRequest, DeferredResult) afterTimeout} 037 * method can set the {@code DeferredResult} in order to resume processing. 038 * 039 * @author Rossen Stoyanchev 040 * @author Rob Winch 041 * @since 3.2 042 */ 043public interface DeferredResultProcessingInterceptor { 044 045 /** 046 * Invoked immediately before the start of concurrent handling, in the same 047 * thread that started it. This method may be used to capture state just prior 048 * to the start of concurrent processing with the given {@code DeferredResult}. 049 * @param request the current request 050 * @param deferredResult the DeferredResult for the current request 051 * @throws Exception in case of errors 052 */ 053 <T> void beforeConcurrentHandling(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 054 055 /** 056 * Invoked immediately after the start of concurrent handling, in the same 057 * thread that started it. This method may be used to detect the start of 058 * concurrent processing with the given {@code DeferredResult}. 059 * <p>The {@code DeferredResult} may have already been set, for example at 060 * the time of its creation or by another thread. 061 * @param request the current request 062 * @param deferredResult the DeferredResult for the current request 063 * @throws Exception in case of errors 064 */ 065 <T> void preProcess(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 066 067 /** 068 * Invoked after a {@code DeferredResult} has been set, via 069 * {@link DeferredResult#setResult(Object)} or 070 * {@link DeferredResult#setErrorResult(Object)}, and is also ready to 071 * handle the concurrent result. 072 * <p>This method may also be invoked after a timeout when the 073 * {@code DeferredResult} was created with a constructor accepting a default 074 * timeout result. 075 * @param request the current request 076 * @param deferredResult the DeferredResult for the current request 077 * @param concurrentResult the result to which the {@code DeferredResult} 078 * @throws Exception in case of errors 079 */ 080 <T> void postProcess(NativeWebRequest request, DeferredResult<T> deferredResult, Object concurrentResult) throws Exception; 081 082 /** 083 * Invoked from a container thread when an async request times out before 084 * the {@code DeferredResult} has been set. Implementations may invoke 085 * {@link DeferredResult#setResult(Object) setResult} or 086 * {@link DeferredResult#setErrorResult(Object) setErrorResult} to resume processing. 087 * @param request the current request 088 * @param deferredResult the DeferredResult for the current request; if the 089 * {@code DeferredResult} is set, then concurrent processing is resumed and 090 * subsequent interceptors are not invoked 091 * @return {@code true} if processing should continue, or {@code false} if 092 * other interceptors should not be invoked 093 * @throws Exception in case of errors 094 */ 095 <T> boolean handleTimeout(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 096 097 /** 098 * Invoked from a container thread when an async request completed for any 099 * reason including timeout and network error. This method is useful for 100 * detecting that a {@code DeferredResult} instance is no longer usable. 101 * @param request the current request 102 * @param deferredResult the DeferredResult for the current request 103 * @throws Exception in case of errors 104 */ 105 <T> void afterCompletion(NativeWebRequest request, DeferredResult<T> deferredResult) throws Exception; 106 107}