From cb2b141d317947f12a88bc47745160d2e9b7c2bc Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 8 Dec 2020 11:59:36 +0100 Subject: [PATCH] Clear path pattern after async result This commit makes sure that the matching pattern attributes is cleared when an async result has been obtained, so that the subsequent dispatch starts from scratch. Closes gh-26239 --- .../function/DefaultAsyncServerResponse.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java index 0fd283445436..48a5e900e7b6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultAsyncServerResponse.java @@ -40,8 +40,11 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.MultiValueMap; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.async.AsyncWebRequest; import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor; import org.springframework.web.context.request.async.WebAsyncManager; import org.springframework.web.context.request.async.WebAsyncUtils; import org.springframework.web.servlet.ModelAndView; @@ -54,6 +57,16 @@ */ final class DefaultAsyncServerResponse extends ErrorHandlingServerResponse implements AsyncServerResponse { + private static final DeferredResultProcessingInterceptor CLEAR_PATTERN_ATTRIBUTE_INTERCEPTOR = + new DeferredResultProcessingInterceptor() { + @Override + public void postProcess(NativeWebRequest request, DeferredResult deferredResult, + Object concurrentResult) { + request.removeAttribute(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE, + RequestAttributes.SCOPE_REQUEST); + } + }; + static final boolean reactiveStreamsPresent = ClassUtils.isPresent( "org.reactivestreams.Publisher", DefaultAsyncServerResponse.class.getClassLoader()); @@ -128,6 +141,7 @@ static void writeAsync(HttpServletRequest request, HttpServletResponse response, WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); asyncManager.setAsyncWebRequest(asyncWebRequest); + asyncManager.registerDeferredResultInterceptors(CLEAR_PATTERN_ATTRIBUTE_INTERCEPTOR); try { asyncManager.startDeferredResultProcessing(deferredResult); }