From e0a7b074ed95f278b782e159436f053d659e28ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0vorc?= Date: Sun, 7 May 2017 20:59:09 +0200 Subject: [PATCH] Use original query string of forwarded request Prior to this commit, the AbstractFlashMapManager has used the originating URI but the query string of the forwarded request. That resulted to FlashMap not being matched even when both originating URI and query string matched the FlashMap attributes. The originating query string is now used to match the forwarded request. Issue: SPR-15505 --- .../support/AbstractFlashMapManager.java | 9 ++++++--- .../servlet/support/FlashMapManagerTests.java | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java index c859a2301a..f32e73806b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java @@ -33,7 +33,6 @@ import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.servlet.FlashMap; import org.springframework.web.servlet.FlashMapManager; -import org.springframework.web.util.UriComponents; import org.springframework.web.util.UrlPathHelper; @@ -173,8 +172,7 @@ public abstract class AbstractFlashMapManager implements FlashMapManager { return false; } } - UriComponents uriComponents = ServletUriComponentsBuilder.fromRequest(request).build(); - MultiValueMap actualParams = uriComponents.getQueryParams(); + MultiValueMap actualParams = getOriginatingRequestParams(request); MultiValueMap expectedParams = flashMap.getTargetRequestParams(); for (String expectedName : expectedParams.keySet()) { List actualValues = actualParams.get(expectedName); @@ -190,6 +188,11 @@ public abstract class AbstractFlashMapManager implements FlashMapManager { return true; } + private MultiValueMap getOriginatingRequestParams(HttpServletRequest request) { + String query = getUrlPathHelper().getOriginatingQueryString(request); + return ServletUriComponentsBuilder.fromPath("/").query(query).build().getQueryParams(); + } + @Override public final void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) { if (CollectionUtils.isEmpty(flashMap)) { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java index 333a093bb6..b0bac5318b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/FlashMapManagerTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.*; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -318,6 +319,25 @@ public class FlashMapManagerTests { assertEquals("value", flashMap.get("key")); } + @Test // SPR-15505 + public void retrieveAndUpdateMatchByOriginatingPathAndQueryString() { + FlashMap flashMap = new FlashMap(); + flashMap.put("key", "value"); + flashMap.setTargetRequestPath("/accounts"); + flashMap.addTargetRequestParam("a", "b"); + + this.flashMapManager.setFlashMaps(Collections.singletonList(flashMap)); + + this.request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/accounts"); + this.request.setAttribute(WebUtils.FORWARD_QUERY_STRING_ATTRIBUTE, "a=b"); + this.request.setRequestURI("/mvc/accounts"); + this.request.setQueryString("x=y"); + FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(this.request, this.response); + + assertEquals(flashMap, inputFlashMap); + assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size()); + } + private static class TestFlashMapManager extends AbstractFlashMapManager {