SPR-9060 Revise HTTP Session based FlashMapManager implementation.
The "default" FlashMapManager implementation added in 3.1 was invoked after the redirect, which is too late in cases where the HTTP session has not been yet been created since as the response is committed. This change corrects the issue and makes other improvements to the FlashMapManager implementation such as extracting a base AbstractFlashMapManager class and making it easier for other implementations to be added (for example cookie-based).
This commit is contained in:
@@ -16,14 +16,16 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.servlet.FlashMapManager;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
@@ -62,7 +64,7 @@ public class ParameterizableViewControllerTests {
|
||||
|
||||
@Test
|
||||
public void handleRequestWithFlashAttributes() throws Exception {
|
||||
this.request.setAttribute(FlashMapManager.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
|
||||
this.request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
|
||||
ModelAndView mav = this.controller.handleRequest(this.request, new MockHttpServletResponse());
|
||||
assertEquals(1, mav.getModel().size());
|
||||
assertEquals("value", mav.getModel().get("name"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.servlet.FlashMapManager;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@@ -155,7 +155,7 @@ public class UrlFilenameViewControllerTests extends TestCase {
|
||||
public void testWithFlashAttributes() throws Exception {
|
||||
UrlFilenameViewController ctrl = new UrlFilenameViewController();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
|
||||
request.setAttribute(FlashMapManager.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
|
||||
request.setAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE, new ModelMap("name", "value"));
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
ModelAndView mv = ctrl.handleRequest(request, response);
|
||||
assertEquals("index", mv.getViewName());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,8 +35,8 @@ import org.springframework.web.method.annotation.ModelMethodProcessor;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.servlet.FlashMapManager;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
@@ -111,7 +111,7 @@ public class RequestMappingHandlerAdapterTests {
|
||||
this.handlerAdapter.setIgnoreDefaultModelOnRedirect(true);
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
|
||||
this.request.setAttribute(FlashMapManager.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
|
||||
this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
|
||||
|
||||
HandlerMethod handlerMethod = handlerMethod(new RedirectAttributeController(), "handle", Model.class);
|
||||
ModelAndView mav = this.handlerAdapter.handle(request, response, handlerMethod);
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.support;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Test fixture for testing {@link AbstractFlashMapManager} methods.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class AbstractFlashMapManagerTests {
|
||||
|
||||
private TestFlashMapManager flashMapManager;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.flashMapManager = new TestFlashMapManager();
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestByPath() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/path");
|
||||
|
||||
this.flashMapManager.setFlashMaps(flashMap);
|
||||
|
||||
this.request.setRequestURI("/path");
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMap, inputFlashMap);
|
||||
assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
// SPR-8779
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestByOriginatingPath() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/accounts");
|
||||
|
||||
this.flashMapManager.setFlashMaps(flashMap);
|
||||
|
||||
this.request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/accounts");
|
||||
this.request.setRequestURI("/mvc/accounts");
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMap, inputFlashMap);
|
||||
assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestByPathWithTrailingSlash() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/path");
|
||||
|
||||
this.flashMapManager.setFlashMaps(flashMap);
|
||||
|
||||
this.request.setRequestURI("/path/");
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMap, inputFlashMap);
|
||||
assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestWithParams() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.addTargetRequestParam("number", "one");
|
||||
|
||||
this.flashMapManager.setFlashMaps(flashMap);
|
||||
|
||||
this.request.setParameter("number", (String) null);
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertNull(inputFlashMap);
|
||||
assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size());
|
||||
|
||||
this.request.setParameter("number", "two");
|
||||
inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertNull(inputFlashMap);
|
||||
assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size());
|
||||
|
||||
this.request.setParameter("number", "one");
|
||||
inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMap, inputFlashMap);
|
||||
assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
// SPR-8798
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestWithMultiValueParam() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("name", "value");
|
||||
flashMap.addTargetRequestParam("id", "1");
|
||||
flashMap.addTargetRequestParam("id", "2");
|
||||
|
||||
this.flashMapManager.setFlashMaps(flashMap);
|
||||
|
||||
this.request.setParameter("id", "1");
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertNull(inputFlashMap);
|
||||
assertEquals("FlashMap should not have been removed", 1, this.flashMapManager.getFlashMaps().size());
|
||||
|
||||
this.request.addParameter("id", "2");
|
||||
inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMap, inputFlashMap);
|
||||
assertEquals("Input FlashMap should have been removed", 0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFlashMapForRequestSortOrder() {
|
||||
FlashMap emptyFlashMap = new FlashMap();
|
||||
|
||||
FlashMap flashMapOne = new FlashMap();
|
||||
flashMapOne.put("key1", "value1");
|
||||
flashMapOne.setTargetRequestPath("/one");
|
||||
|
||||
FlashMap flashMapTwo = new FlashMap();
|
||||
flashMapTwo.put("key1", "value1");
|
||||
flashMapTwo.put("key2", "value2");
|
||||
flashMapTwo.setTargetRequestPath("/one/two");
|
||||
|
||||
this.flashMapManager.setFlashMaps(emptyFlashMap, flashMapOne, flashMapTwo);
|
||||
|
||||
this.request.setRequestURI("/one/two");
|
||||
Map<String, ?> inputFlashMap = this.flashMapManager.getFlashMapForRequest(this.request);
|
||||
|
||||
assertEquals(flashMapTwo, inputFlashMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapEmpty() throws InterruptedException {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
List<FlashMap> allMaps = this.flashMapManager.getFlashMaps();
|
||||
|
||||
assertNull(allMaps);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMap() throws InterruptedException {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("name", "value");
|
||||
|
||||
this.flashMapManager.setFlashMapTimeout(-1); // expire immediately so we can check expiration started
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
List<FlashMap> allMaps = this.flashMapManager.getFlashMaps();
|
||||
|
||||
assertNotNull(allMaps);
|
||||
assertSame(flashMap, allMaps.get(0));
|
||||
assertTrue(flashMap.isExpired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapDecodeTargetPath() throws InterruptedException {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
|
||||
flashMap.setTargetRequestPath("/once%20upon%20a%20time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once upon a time", flashMap.getTargetRequestPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapNormalizeTargetPath() throws InterruptedException {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
|
||||
flashMap.setTargetRequestPath(".");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/a", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("./");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/a/", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("..");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("../");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("../../only");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.save(flashMap, this.request, this.response);
|
||||
|
||||
assertEquals("/once/only", flashMap.getTargetRequestPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapAndRemoveExpired() throws InterruptedException {
|
||||
List<FlashMap> flashMaps = new ArrayList<FlashMap>();
|
||||
for (int i=0; i < 5; i++) {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.startExpirationPeriod(-1);
|
||||
flashMaps.add(flashMap);
|
||||
}
|
||||
this.flashMapManager.setFlashMaps(flashMaps);
|
||||
this.flashMapManager.save(new FlashMap(), request, response);
|
||||
|
||||
assertEquals("Expired instances should be removed even if the saved FlashMap is empty",
|
||||
0, this.flashMapManager.getFlashMaps().size());
|
||||
}
|
||||
|
||||
|
||||
private static class TestFlashMapManager extends AbstractFlashMapManager {
|
||||
|
||||
private List<FlashMap> flashMaps;
|
||||
|
||||
public List<FlashMap> getFlashMaps() {
|
||||
return this.flashMaps;
|
||||
}
|
||||
|
||||
public void setFlashMaps(FlashMap... flashMaps) {
|
||||
setFlashMaps(Arrays.asList(flashMaps));
|
||||
}
|
||||
|
||||
public void setFlashMaps(List<FlashMap> flashMaps) {
|
||||
this.flashMaps = new CopyOnWriteArrayList<FlashMap>(flashMaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request) {
|
||||
return this.flashMaps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
this.flashMaps = flashMaps;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.support;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.web.servlet.FlashMapManager.INPUT_FLASH_MAP_ATTRIBUTE;
|
||||
import static org.springframework.web.servlet.FlashMapManager.OUTPUT_FLASH_MAP_ATTRIBUTE;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link DefaultFlashMapManager} tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class DefaultFlashMapManagerTests {
|
||||
|
||||
private DefaultFlashMapManager flashMapManager;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.flashMapManager = new DefaultFlashMapManager();
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestStarted() {
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
|
||||
|
||||
assertNotNull("Current FlashMap not found", flashMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestStartedAlready() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
this.request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap);
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertSame(flashMap, RequestContextUtils.getOutputFlashMap(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapByPath() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/path");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(flashMap);
|
||||
|
||||
this.request.setRequestURI("/path");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMap, RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("Input FlashMap should have been removed", 0, getFlashMaps().size());
|
||||
}
|
||||
|
||||
// SPR-8779
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapByOriginatingPath() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/accounts");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(flashMap);
|
||||
|
||||
this.request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/accounts");
|
||||
this.request.setRequestURI("/mvc/accounts");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMap, RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("Input FlashMap should have been removed", 0, getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapByPathWithTrailingSlash() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.setTargetRequestPath("/path");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(flashMap);
|
||||
|
||||
this.request.setRequestURI("/path/");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMap, RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("Input FlashMap should have been removed", 0, getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapWithParams() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("key", "value");
|
||||
flashMap.addTargetRequestParam("number", "one");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(flashMap);
|
||||
|
||||
this.request.setParameter("number", (String) null);
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertNull(RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("FlashMap should not have been removed", 1, getFlashMaps().size());
|
||||
|
||||
clearFlashMapRequestAttributes();
|
||||
this.request.setParameter("number", "two");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertNull(RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("FlashMap should not have been removed", 1, getFlashMaps().size());
|
||||
|
||||
clearFlashMapRequestAttributes();
|
||||
this.request.setParameter("number", "one");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMap, RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("Input FlashMap should have been removed", 0, getFlashMaps().size());
|
||||
}
|
||||
|
||||
// SPR-8798
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapWithMultiValueParam() {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("name", "value");
|
||||
flashMap.addTargetRequestParam("id", "1");
|
||||
flashMap.addTargetRequestParam("id", "2");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(flashMap);
|
||||
|
||||
this.request.setParameter("id", "1");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertNull(RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("FlashMap should not have been removed", 1, getFlashMaps().size());
|
||||
|
||||
clearFlashMapRequestAttributes();
|
||||
this.request.addParameter("id", "2");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMap, RequestContextUtils.getInputFlashMap(this.request));
|
||||
assertEquals("Input FlashMap should have been removed", 0, getFlashMaps().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupFlashMapSortOrder() {
|
||||
FlashMap emptyFlashMap = new FlashMap();
|
||||
|
||||
FlashMap flashMapOne = new FlashMap();
|
||||
flashMapOne.put("key1", "value1");
|
||||
flashMapOne.setTargetRequestPath("/one");
|
||||
|
||||
FlashMap flashMapTwo = new FlashMap();
|
||||
flashMapTwo.put("key1", "value1");
|
||||
flashMapTwo.put("key2", "value2");
|
||||
flashMapTwo.setTargetRequestPath("/one/two");
|
||||
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
allMaps.add(emptyFlashMap);
|
||||
allMaps.add(flashMapOne);
|
||||
allMaps.add(flashMapTwo);
|
||||
Collections.shuffle(allMaps);
|
||||
|
||||
this.request.setRequestURI("/one/two");
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(flashMapTwo, request.getAttribute(INPUT_FLASH_MAP_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeExpiredFlashMaps() throws InterruptedException {
|
||||
List<FlashMap> allMaps = createFlashMaps();
|
||||
for (int i=0; i < 5; i++) {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
allMaps.add(flashMap);
|
||||
flashMap.startExpirationPeriod(0);
|
||||
}
|
||||
Thread.sleep(100);
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
|
||||
assertEquals(0, allMaps.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapWithoutAttributes() throws InterruptedException {
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertNull(getFlashMaps());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapNotCreatedByThisManager() throws InterruptedException {
|
||||
FlashMap flashMap = new FlashMap();
|
||||
this.request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap);
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertNull(getFlashMaps());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveFlashMapWithAttributes() throws InterruptedException {
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(this.request);
|
||||
flashMap.put("name", "value");
|
||||
|
||||
this.flashMapManager.setFlashMapTimeout(0);
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
List<FlashMap> allMaps = getFlashMaps();
|
||||
|
||||
assertNotNull(allMaps);
|
||||
assertSame(flashMap, allMaps.get(0));
|
||||
assertTrue(flashMap.isExpired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeTargetPath() throws InterruptedException {
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(this.request);
|
||||
flashMap.put("key", "value");
|
||||
|
||||
flashMap.setTargetRequestPath("/once%20upon%20a%20time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once upon a time", flashMap.getTargetRequestPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalizeTargetPath() throws InterruptedException {
|
||||
this.flashMapManager.requestStarted(this.request, this.response);
|
||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(this.request);
|
||||
flashMap.put("key", "value");
|
||||
|
||||
flashMap.setTargetRequestPath(".");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/a", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("./");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/a/", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("..");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("../");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once/upon/", flashMap.getTargetRequestPath());
|
||||
|
||||
flashMap.setTargetRequestPath("../../only");
|
||||
this.request.setRequestURI("/once/upon/a/time");
|
||||
this.flashMapManager.requestCompleted(this.request, this.response);
|
||||
|
||||
assertEquals("/once/only", flashMap.getTargetRequestPath());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<FlashMap> getFlashMaps() {
|
||||
return (List<FlashMap>) this.request.getSession().getAttribute(DefaultFlashMapManager.class.getName() + ".FLASH_MAPS");
|
||||
}
|
||||
|
||||
private List<FlashMap> createFlashMaps() {
|
||||
List<FlashMap> allMaps = new CopyOnWriteArrayList<FlashMap>();
|
||||
this.request.getSession().setAttribute(DefaultFlashMapManager.class.getName() + ".FLASH_MAPS", allMaps);
|
||||
return allMaps;
|
||||
}
|
||||
|
||||
private void clearFlashMapRequestAttributes() {
|
||||
request.removeAttribute(INPUT_FLASH_MAP_ATTRIBUTE);
|
||||
request.removeAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,8 +48,9 @@ import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.servlet.FlashMapManager;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.support.RequestDataValueProcessorWrapper;
|
||||
import org.springframework.web.servlet.support.RequestDataValueProcessor;
|
||||
import org.springframework.web.servlet.support.RequestDataValueProcessorWrapper;
|
||||
import org.springframework.web.servlet.support.SessionFlashMapManager;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
@@ -75,20 +76,29 @@ public class RedirectViewTests {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("http://url.somewhere.com");
|
||||
rv.setHttp10Compatible(false);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
|
||||
request.setAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE, new SessionFlashMapManager());
|
||||
rv.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals(303, response.getStatus());
|
||||
assertEquals("http://url.somewhere.com", response.getHeader("Location"));
|
||||
}
|
||||
|
||||
private MockHttpServletRequest createRequest() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
|
||||
request.setAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE, new SessionFlashMapManager());
|
||||
return request;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void explicitStatusCodeHttp11() throws Exception {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("http://url.somewhere.com");
|
||||
rv.setHttp10Compatible(false);
|
||||
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
rv.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals(301, response.getStatus());
|
||||
@@ -100,7 +110,7 @@ public class RedirectViewTests {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("http://url.somewhere.com");
|
||||
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
rv.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals(301, response.getStatus());
|
||||
@@ -112,7 +122,7 @@ public class RedirectViewTests {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("http://url.somewhere.com");
|
||||
rv.setHttp10Compatible(false);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.CREATED);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
rv.render(new HashMap<String, Object>(), request, response);
|
||||
@@ -125,11 +135,11 @@ public class RedirectViewTests {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("http://url.somewhere.com/path");
|
||||
rv.setHttp10Compatible(false);
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
FlashMap flashMap = new FlashMap();
|
||||
flashMap.put("successMessage", "yay!");
|
||||
request.setAttribute(FlashMapManager.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap);
|
||||
request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, flashMap);
|
||||
ModelMap model = new ModelMap("id", "1");
|
||||
rv.render(model, request, response);
|
||||
assertEquals(303, response.getStatus());
|
||||
@@ -153,7 +163,7 @@ public class RedirectViewTests {
|
||||
rv.setApplicationContext(wac); // Init RedirectView with WebAppCxt
|
||||
rv.setUrl("/path");
|
||||
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@@ -182,7 +192,7 @@ public class RedirectViewTests {
|
||||
RedirectView rv = new RedirectView();
|
||||
rv.setUrl("/path");
|
||||
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletRequest request = createRequest();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
EasyMock.expect(mockProcessor.processUrl(request, "/path")).andReturn("/path?key=123");
|
||||
@@ -361,6 +371,11 @@ public class RedirectViewTests {
|
||||
expectedUrlForEncoding = "/context" + expectedUrlForEncoding;
|
||||
expect(request.getContextPath()).andReturn("/context");
|
||||
}
|
||||
|
||||
expect(request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE)).andReturn(new FlashMap());
|
||||
|
||||
FlashMapManager flashMapManager = new SessionFlashMapManager();
|
||||
expect(request.getAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE)).andReturn(flashMapManager);
|
||||
|
||||
HttpServletResponse response = createMock("response", HttpServletResponse.class);
|
||||
expect(response.encodeRedirectURL(expectedUrlForEncoding)).andReturn(expectedUrlForEncoding);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,10 @@ import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.support.SessionFlashMapManager;
|
||||
|
||||
public class RedirectViewUriTemplateTests {
|
||||
|
||||
@@ -38,6 +41,8 @@ public class RedirectViewUriTemplateTests {
|
||||
public void setUp() {
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
this.request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
|
||||
this.request.setAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE, new SessionFlashMapManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user