Merge branch '3.1.x'

Conflicts:
	spring-webmvc/src/main/java/org/springframework/web/servlet/support/DefaultFlashMapManager.java
	spring-webmvc/src/test/java/org/springframework/web/servlet/support/DefaultFlashMapManagerTests.java
This commit is contained in:
Chris Beams
2012-02-01 11:39:48 +01:00
16 changed files with 685 additions and 664 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.
@@ -208,7 +208,27 @@ public class DispatcherServlet extends FrameworkServlet {
* @see org.springframework.web.servlet.support.RequestContextUtils#getThemeSource
*/
public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
/**
* Name of request attribute that holds a read-only {@code Map<String,?>}
* with "input" flash attributes saved by a previous request, if any.
* @see org.springframework.web.servlet.support.RequestContextUtils#getInputFlashMap(HttpServletRequest)
*/
public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
/**
* Name of request attribute that holds the "output" {@link FlashMap} with
* attributes to save for a subsequent request.
* @see org.springframework.web.servlet.support.RequestContextUtils#getOutputFlashMap(HttpServletRequest)
*/
public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
/**
* Name of request attribute that holds the {@link FlashMapManager}.
* @see org.springframework.web.servlet.support.RequestContextUtils#getFlashMapManager(HttpServletRequest)
*/
public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
/** Log category to use when no mapped handler is found for a request. */
public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
@@ -815,20 +835,23 @@ public class DispatcherServlet extends FrameworkServlet {
}
}
this.flashMapManager.requestStarted(request, response);
// Make framework objects available to handlers and view objects.
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
Map<String, ?> flashMap = this.flashMapManager.getFlashMapForRequest(request);
if (flashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, flashMap);
}
try {
doDispatch(request, response);
}
finally {
this.flashMapManager.requestCompleted(request, response);
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);

View File

@@ -21,4 +21,4 @@ org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.DefaultFlashMapManager
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

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.
@@ -16,22 +16,14 @@
package org.springframework.web.servlet;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A strategy interface for storing, retrieving, and managing {@code FlashMap}
* instances. See {@link FlashMap} for a general overview of flash attributes.
*
* <p>A FlashMapManager is invoked at the beginning and at the end of requests.
* For each request it retrieves an "input" FlashMap with attributes passed
* from a previous request (if any) and creates an "output" FlashMap with
* attributes to pass to a subsequent request. "Input" and "output" FlashMap
* instances are exposed as request attributes and are accessible via methods
* in {@code org.springframework.web.servlet.support.RequestContextUtils}.
*
* <p>Annotated controllers will usually not use this FlashMap directly.
* See {@code org.springframework.web.servlet.mvc.support.RedirectAttributes}.
* A strategy interface for retrieving and saving FlashMap instances.
* See {@link FlashMap} for a general overview of flash attributes.
*
* @author Rossen Stoyanchev
* @since 3.1
@@ -41,42 +33,27 @@ import javax.servlet.http.HttpServletResponse;
public interface FlashMapManager {
/**
* Name of request attribute that holds a read-only
* {@code Map<String, Object>} with "input" flash attributes if any.
* @see org.springframework.web.servlet.support.RequestContextUtils#getInputFlashMap(HttpServletRequest)
* Get a Map with flash attributes saved by a previous request.
* See {@link FlashMap} for details on how FlashMap instances
* identifies the target requests they're saved for.
* If found, the Map is removed from the underlying storage.
* @param request the current request
* @return a read-only Map with flash attributes or {@code null}
*/
String INPUT_FLASH_MAP_ATTRIBUTE = FlashMapManager.class.getName() + ".INPUT_FLASH_MAP";
Map<String, ?> getFlashMapForRequest(HttpServletRequest request);
/**
* Name of request attribute that holds the "output" {@link FlashMap} with
* attributes to save for a subsequent request.
* @see org.springframework.web.servlet.support.RequestContextUtils#getOutputFlashMap(HttpServletRequest)
*/
String OUTPUT_FLASH_MAP_ATTRIBUTE = FlashMapManager.class.getName() + ".OUTPUT_FLASH_MAP";
/**
* Perform the following tasks unless the {@link #OUTPUT_FLASH_MAP_ATTRIBUTE}
* request attribute exists:
* <ol>
* <li>Find the "input" FlashMap, expose it under the request attribute
* {@link #INPUT_FLASH_MAP_ATTRIBUTE}, and remove it from underlying storage.
* <li>Create the "output" FlashMap and expose it under the request
* attribute {@link #OUTPUT_FLASH_MAP_ATTRIBUTE}.
* <li>Clean expired FlashMap instances.
* </ol>
* Save the given FlashMap, in some underlying storage, mark the beginning
* of its expiration period, and remove other expired FlashMap instances.
* The method has no impact if the FlashMap is empty and there are no
* expired FlashMap instances to be removed.
* <p><strong>Note:</strong> Invoke this method prior to a redirect in order
* to allow saving the FlashMap in the HTTP session or perhaps in a response
* cookie before the response is committed.
* @param flashMap the FlashMap to save
* @param request the current request
* @param response the current response
*/
void requestStarted(HttpServletRequest request, HttpServletResponse response);
/**
* Start the expiration period of the "output" FlashMap save it in the
* underlying storage.
* <p>The "output" FlashMap should not be saved if it is empty or if it was
* not created by the current FlashMapManager instance.
* @param request the current request
* @param response the current response
*/
void requestCompleted(HttpServletRequest request, HttpServletResponse response);
void save(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -0,0 +1,221 @@
/*
* 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 java.util.ArrayList;
import java.util.Collections;
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.util.UrlPathHelper;
/**
* A base class for {@link FlashMapManager} implementations.
*
* @author Rossen Stoyanchev
* @since 3.1.1
*/
public abstract class AbstractFlashMapManager implements FlashMapManager {
protected final Log logger = LogFactory.getLog(getClass());
private int flashMapTimeout = 180;
private UrlPathHelper urlPathHelper = new UrlPathHelper();
/**
* Set the amount of time in seconds after a {@link FlashMap} is saved
* (at request completion) and before it expires.
* <p>The default value is 180 seconds.
*/
public void setFlashMapTimeout(int flashMapTimeout) {
this.flashMapTimeout = flashMapTimeout;
}
/**
* Return the amount of time in seconds before a FlashMap expires.
*/
public int getFlashMapTimeout() {
return this.flashMapTimeout;
}
/**
* Set the UrlPathHelper to use to match FlashMap instances to requests.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Return the UrlPathHelper implementation to use.
*/
public UrlPathHelper getUrlPathHelper() {
return this.urlPathHelper;
}
/**
* {@inheritDoc}
* <p>Does not cause an HTTP session to be created.
*/
public final Map<String, ?> getFlashMapForRequest(HttpServletRequest request) {
List<FlashMap> flashMaps = retrieveFlashMaps(request);
if (CollectionUtils.isEmpty(flashMaps)) {
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Retrieved FlashMap(s): " + flashMaps);
}
List<FlashMap> result = new ArrayList<FlashMap>();
for (FlashMap flashMap : flashMaps) {
if (isFlashMapForRequest(flashMap, request)) {
result.add(flashMap);
}
}
if (!result.isEmpty()) {
Collections.sort(result);
if (logger.isDebugEnabled()) {
logger.debug("Found matching FlashMap(s): " + result);
}
FlashMap match = result.remove(0);
flashMaps.remove(match);
return Collections.unmodifiableMap(match);
}
return null;
}
/**
* Retrieve saved FlashMap instances from underlying storage.
* @param request the current request
* @return a List with FlashMap instances or {@code null}
*/
protected abstract List<FlashMap> retrieveFlashMaps(HttpServletRequest request);
/**
* Whether the given FlashMap matches the current request.
* The default implementation uses the target request path and query params
* saved in the FlashMap.
*/
protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) {
if (flashMap.getTargetRequestPath() != null) {
String requestUri = this.urlPathHelper.getOriginatingRequestUri(request);
if (!requestUri.equals(flashMap.getTargetRequestPath())
&& !requestUri.equals(flashMap.getTargetRequestPath() + "/")) {
return false;
}
}
MultiValueMap<String, String> targetParams = flashMap.getTargetRequestParams();
for (String paramName : targetParams.keySet()) {
for (String targetValue : targetParams.get(paramName)) {
if (!ObjectUtils.containsElement(request.getParameterValues(paramName), targetValue)) {
return false;
}
}
}
return true;
}
/**
* {@inheritDoc}
* <p>The FlashMap, if not empty, is saved to the HTTP session.
*/
public final void save(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) {
Assert.notNull(flashMap, "FlashMap must not be null");
List<FlashMap> flashMaps = retrieveFlashMaps(request);
if (flashMap.isEmpty() && (flashMaps == null)) {
return;
}
synchronized (this) {
boolean update = false;
flashMaps = retrieveFlashMaps(request);
if (!CollectionUtils.isEmpty(flashMaps)) {
update = removeExpired(flashMaps);
}
if (!flashMap.isEmpty()) {
String path = decodeAndNormalizePath(flashMap.getTargetRequestPath(), request);
flashMap.setTargetRequestPath(path);
flashMap.startExpirationPeriod(this.flashMapTimeout);
if (logger.isDebugEnabled()) {
logger.debug("Saving FlashMap=" + flashMap);
}
flashMaps = (flashMaps == null) ? new CopyOnWriteArrayList<FlashMap>() : flashMaps;
flashMaps.add(flashMap);
update = true;
}
if (update) {
updateFlashMaps(flashMaps, request, response);
}
}
}
private String decodeAndNormalizePath(String path, HttpServletRequest request) {
if (path != null) {
path = this.urlPathHelper.decodeRequestString(request, path);
if (path.charAt(0) != '/') {
String requestUri = this.urlPathHelper.getRequestUri(request);
path = requestUri.substring(0, requestUri.lastIndexOf('/') + 1) + path;
path = StringUtils.cleanPath(path);
}
}
return path;
}
/**
* Update the FlashMap instances in some underlying storage.
* @param flashMaps a non-empty list of FlashMap instances to save
* @param request the current request
* @param response the current response
*/
protected abstract void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request,
HttpServletResponse response);
/**
* Remove expired FlashMap instances from the given List.
*/
protected boolean removeExpired(List<FlashMap> flashMaps) {
List<FlashMap> expired = new ArrayList<FlashMap>();
for (FlashMap flashMap : flashMaps) {
if (flashMap.isExpired()) {
if (logger.isTraceEnabled()) {
logger.trace("Removing expired FlashMap: " + flashMap);
}
expired.add(flashMap);
}
}
if (expired.isEmpty()) {
return false;
}
else {
return flashMaps.removeAll(expired);
}
}
}

View File

@@ -1,266 +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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.util.UrlPathHelper;
/**
* A default {@link FlashMapManager} implementation that stores {@link FlashMap}
* instances in the HTTP session.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public class DefaultFlashMapManager implements FlashMapManager {
private static final String FLASH_MAPS_SESSION_ATTRIBUTE = DefaultFlashMapManager.class.getName() + ".FLASH_MAPS";
private static final Log logger = LogFactory.getLog(DefaultFlashMapManager.class);
private int flashMapTimeout = 180;
private UrlPathHelper urlPathHelper = new UrlPathHelper();
/**
* Set the amount of time in seconds after a {@link FlashMap} is saved
* (at request completion) and before it expires.
* <p>The default value is 180 seconds.
*/
public void setFlashMapTimeout(int flashMapTimeout) {
this.flashMapTimeout = flashMapTimeout;
}
/**
* Return the amount of time in seconds before a FlashMap expires.
*/
public int getFlashMapTimeout() {
return flashMapTimeout;
}
/**
* Set the UrlPathHelper to use to obtain the request URI.
*/
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
this.urlPathHelper = urlPathHelper;
}
/**
* Return the UrlPathHelper implementation for the request URI.
*/
public UrlPathHelper getUrlPathHelper() {
return urlPathHelper;
}
/**
* {@inheritDoc}
* <p>An HTTP session is never created by this method.
*/
public final void requestStarted(HttpServletRequest request, HttpServletResponse response) {
if (request.getAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE) != null) {
return;
}
FlashMap inputFlashMap = lookupFlashMap(request);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
FlashMap outputFlashMap = new FlashMap(this.hashCode());
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, outputFlashMap);
removeExpiredFlashMaps(request);
}
/**
* Find the "input" FlashMap for the current request target by matching it
* to the target request information of all stored FlashMap instances.
* @return a FlashMap instance or {@code null}
*/
private FlashMap lookupFlashMap(HttpServletRequest request) {
List<FlashMap> allFlashMaps = retrieveFlashMaps(request, false);
if (CollectionUtils.isEmpty(allFlashMaps)) {
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Retrieved FlashMap(s): " + allFlashMaps);
}
List<FlashMap> result = new ArrayList<FlashMap>();
for (FlashMap flashMap : allFlashMaps) {
if (isFlashMapForRequest(flashMap, request)) {
result.add(flashMap);
}
}
if (!result.isEmpty()) {
Collections.sort(result);
if (logger.isDebugEnabled()) {
logger.debug("Found matching FlashMap(s): " + result);
}
FlashMap match = result.remove(0);
allFlashMaps.remove(match);
return match;
}
return null;
}
/**
* Whether the given FlashMap matches the current request.
* The default implementation uses the target request path and query params
* saved in the FlashMap.
*/
protected boolean isFlashMapForRequest(FlashMap flashMap, HttpServletRequest request) {
if (flashMap.getTargetRequestPath() != null) {
String requestUri = this.urlPathHelper.getOriginatingRequestUri(request);
if (!requestUri.equals(flashMap.getTargetRequestPath())
&& !requestUri.equals(flashMap.getTargetRequestPath() + "/")) {
return false;
}
}
MultiValueMap<String, String> targetParams = flashMap.getTargetRequestParams();
for (String paramName : targetParams.keySet()) {
for (String targetValue : targetParams.get(paramName)) {
if (!ObjectUtils.containsElement(request.getParameterValues(paramName), targetValue)) {
return false;
}
}
}
return true;
}
/**
* Retrieve all FlashMap instances from the current HTTP session.
* If {@code allowCreate} is "true" and no flash maps exist yet, a new list
* is created and stored as a session attribute.
* @param request the current request
* @param allowCreate whether to create the session if necessary
* @return a List to add FlashMap instances to or {@code null}
* assuming {@code allowCreate} is "false".
*/
@SuppressWarnings("unchecked")
protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request, boolean allowCreate) {
HttpSession session = request.getSession(allowCreate);
if (session == null) {
return null;
}
List<FlashMap> allFlashMaps = (List<FlashMap>) session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE);
if (allFlashMaps == null && allowCreate) {
synchronized (this) {
allFlashMaps = (List<FlashMap>) session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE);
if (allFlashMaps == null) {
allFlashMaps = new CopyOnWriteArrayList<FlashMap>();
session.setAttribute(FLASH_MAPS_SESSION_ATTRIBUTE, allFlashMaps);
}
}
}
return allFlashMaps;
}
/**
* Check and remove expired FlashMaps instances.
*/
protected void removeExpiredFlashMaps(HttpServletRequest request) {
List<FlashMap> allMaps = retrieveFlashMaps(request, false);
if (CollectionUtils.isEmpty(allMaps)) {
return;
}
List<FlashMap> expiredMaps = new ArrayList<FlashMap>();
for (FlashMap flashMap : allMaps) {
if (flashMap.isExpired()) {
if (logger.isDebugEnabled()) {
logger.debug("Removing expired FlashMap: " + flashMap);
}
expiredMaps.add(flashMap);
}
}
if (!expiredMaps.isEmpty()) {
allMaps.removeAll(expiredMaps);
}
}
/**
* {@inheritDoc}
* <p>An HTTP session is never created if the "output" FlashMap is empty.
*/
public void requestCompleted(HttpServletRequest request, HttpServletResponse response) {
FlashMap flashMap = (FlashMap) request.getAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE);
if (flashMap == null) {
throw new IllegalStateException("requestCompleted called but \"output\" FlashMap was never created");
}
if (!flashMap.isEmpty() && flashMap.isCreatedBy(this.hashCode())) {
if (logger.isDebugEnabled()) {
logger.debug("Saving FlashMap=" + flashMap);
}
onSaveFlashMap(flashMap, request, response);
saveFlashMap(flashMap, request, response);
}
}
/**
* Update a FlashMap before it is stored in the underlying storage.
* <p>The default implementation starts the expiration period and ensures the
* target request path is decoded and normalized if it is relative.
* @param flashMap the flash map to be saved
* @param request the current request
* @param response the current response
*/
protected void onSaveFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) {
String targetPath = flashMap.getTargetRequestPath();
flashMap.setTargetRequestPath(decodeAndNormalizePath(targetPath, request));
flashMap.startExpirationPeriod(this.flashMapTimeout);
}
/**
* Save the FlashMap in the underlying storage.
* @param flashMap the FlashMap to save
* @param request the current request
* @param response the current response
*/
protected void saveFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response) {
retrieveFlashMaps(request, true).add(flashMap);
}
private String decodeAndNormalizePath(String path, HttpServletRequest request) {
if (path != null) {
path = this.urlPathHelper.decodeRequestString(request, path);
if (path.charAt(0) != '/') {
String requestUri = this.urlPathHelper.getRequestUri(request);
path = requestUri.substring(0, requestUri.lastIndexOf('/') + 1) + path;
path = StringUtils.cleanPath(path);
}
}
return path;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 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.
@@ -165,7 +165,7 @@ public abstract class RequestContextUtils {
*/
@SuppressWarnings("unchecked")
public static Map<String, ?> getInputFlashMap(HttpServletRequest request) {
return (Map<String, ?>) request.getAttribute(FlashMapManager.INPUT_FLASH_MAP_ATTRIBUTE);
return (Map<String, ?>) request.getAttribute(DispatcherServlet.INPUT_FLASH_MAP_ATTRIBUTE);
}
/**
@@ -175,7 +175,16 @@ public abstract class RequestContextUtils {
* @see FlashMap
*/
public static FlashMap getOutputFlashMap(HttpServletRequest request) {
return (FlashMap) request.getAttribute(FlashMapManager.OUTPUT_FLASH_MAP_ATTRIBUTE);
return (FlashMap) request.getAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE);
}
/**
* Return the FlashMapManager instance to save flash attributes with
* before a redirect.
* @param request the current request
*/
public static FlashMapManager getFlashMapManager(HttpServletRequest request) {
return (FlashMapManager) request.getAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE);
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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 java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.FlashMap;
/**
* Stores {@link FlashMap} instances in the HTTP session.
*
* @author Rossen Stoyanchev
* @since 3.1.1
*/
public class SessionFlashMapManager extends AbstractFlashMapManager{
private static final String FLASH_MAPS_SESSION_ATTRIBUTE = SessionFlashMapManager.class.getName() + ".FLASH_MAPS";
/**
* Retrieve saved FlashMap instances from the HTTP session.
* @param request the current request
* @return a List with FlashMap instances or {@code null}
*/
@SuppressWarnings("unchecked")
protected List<FlashMap> retrieveFlashMaps(HttpServletRequest request) {
HttpSession session = request.getSession(false);
return (session != null) ? (List<FlashMap>) session.getAttribute(FLASH_MAPS_SESSION_ATTRIBUTE) : null;
}
/**
* Save the given FlashMap instances in the HTTP session.
*/
protected void updateFlashMaps(List<FlashMap> flashMaps, HttpServletRequest request, HttpServletResponse response) {
request.getSession().setAttribute(FLASH_MAPS_SESSION_ATTRIBUTE, flashMaps);
}
}

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.
@@ -41,6 +41,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.SmartView;
import org.springframework.web.servlet.View;
@@ -273,7 +274,10 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
flashMap.setTargetRequestPath(uriComponents.getPath());
flashMap.addTargetRequestParams(uriComponents.getQueryParams());
}
FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
flashMapManager.save(flashMap, request, response);
sendRedirect(request, response, targetUrl.toString(), this.http10Compatible);
}