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:
Rossen Stoyanchev
2012-01-31 22:10:55 -05:00
parent f3c3babfdf
commit 3d1fa4f6b6
16 changed files with 685 additions and 664 deletions

View File

@@ -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"));

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

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