From d8166d615550cd467112d7c6d97e872347fa45f0 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Sun, 14 Oct 2012 21:37:29 -0400 Subject: [PATCH] Decode target parameters prior to saving a FlashMap The target parameters for a FlashMap must be decoded to be able to match them to the parameters of incoming requests given that the HttpServletRequest returns decoded request parameters. Issue: SPR-9657 Backport Issue: SPR-9701 --- .../servlet/support/AbstractFlashMapManager.java | 16 +++++++++++++++- .../support/AbstractFlashMapManagerTests.java | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java index e745cfb47b8..1924ad73ce4 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/support/AbstractFlashMapManager.java @@ -177,12 +177,18 @@ public abstract class AbstractFlashMapManager implements FlashMapManager { if (CollectionUtils.isEmpty(flashMap)) { return; } + String path = decodeAndNormalizePath(flashMap.getTargetRequestPath(), request); flashMap.setTargetRequestPath(path); - flashMap.startExpirationPeriod(this.flashMapTimeout); + + decodeParameters(flashMap.getTargetRequestParams(), request); + if (logger.isDebugEnabled()) { logger.debug("Saving FlashMap=" + flashMap); } + + flashMap.startExpirationPeriod(this.flashMapTimeout); + synchronized (writeLock) { List allMaps = retrieveFlashMaps(request); allMaps = (allMaps == null) ? new CopyOnWriteArrayList() : allMaps; @@ -203,6 +209,14 @@ public abstract class AbstractFlashMapManager implements FlashMapManager { return path; } + private void decodeParameters(MultiValueMap params, HttpServletRequest request) { + for (String name : new ArrayList(params.keySet())) { + for (String value : new ArrayList(params.remove(name))) { + params.add(name, this.urlPathHelper.decodeRequestString(request, value)); + } + } + } + /** * Update the FlashMap instances in some underlying storage. * @param flashMaps a non-empty list of FlashMap instances to save diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/AbstractFlashMapManagerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/AbstractFlashMapManagerTests.java index f4b80f6b1ad..5c1bc7a8989 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/AbstractFlashMapManagerTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/AbstractFlashMapManagerTests.java @@ -264,6 +264,22 @@ public class AbstractFlashMapManagerTests { assertEquals("/once/only", flashMap.getTargetRequestPath()); } + @Test + public void saveOutputFlashMapDecodeParameters() throws Exception { + this.request.setCharacterEncoding("UTF-8"); + + FlashMap flashMap = new FlashMap(); + flashMap.put("anyKey", "anyValue"); + + flashMap.addTargetRequestParam("key", "%D0%90%D0%90"); + flashMap.addTargetRequestParam("key", "%D0%91%D0%91"); + flashMap.addTargetRequestParam("key", "%D0%92%D0%92"); + this.flashMapManager.saveOutputFlashMap(flashMap, this.request, this.response); + + assertEquals(Arrays.asList("\u0410\u0410", "\u0411\u0411", "\u0412\u0412"), + flashMap.getTargetRequestParams().get("key")); + } + private static class TestFlashMapManager extends AbstractFlashMapManager {