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
This commit is contained in:
Martin Švorc 2017-05-07 20:59:09 +02:00 committed by Rossen Stoyanchev
parent 4fc41eeeb9
commit e0a7b074ed
2 changed files with 26 additions and 3 deletions

View File

@ -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<String, String> actualParams = uriComponents.getQueryParams();
MultiValueMap<String, String> actualParams = getOriginatingRequestParams(request);
MultiValueMap<String, String> expectedParams = flashMap.getTargetRequestParams();
for (String expectedName : expectedParams.keySet()) {
List<String> actualValues = actualParams.get(expectedName);
@ -190,6 +188,11 @@ public abstract class AbstractFlashMapManager implements FlashMapManager {
return true;
}
private MultiValueMap<String, String> 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)) {

View File

@ -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 {