Browse Source

Only retrieve the FlashMapManager if a non-empty output FlashMap has been found

Issue: SPR-10937
(cherry picked from commit 4ac6801)
pull/405/head
Juergen Hoeller 12 years ago
parent
commit
70907fd326
  1. 9
      spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java
  2. 49
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java

9
spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContextUtils.java

@ -18,7 +18,6 @@ package org.springframework.web.servlet.support;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -41,6 +40,7 @@ import org.springframework.web.servlet.ThemeResolver;
* Locale, ThemeResolver, Theme, and MultipartResolver. * Locale, ThemeResolver, Theme, and MultipartResolver.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Rossen Stoyanchev
* @since 03.03.2003 * @since 03.03.2003
* @see RequestContext * @see RequestContext
* @see org.springframework.web.servlet.DispatcherServlet * @see org.springframework.web.servlet.DispatcherServlet
@ -160,7 +160,7 @@ public abstract class RequestContextUtils {
* Return a read-only {@link Map} with "input" flash attributes saved on a * Return a read-only {@link Map} with "input" flash attributes saved on a
* previous request. * previous request.
* @param request the current request * @param request the current request
* @return a read-only Map, or {@code null} * @return a read-only Map, or {@code null} if not found
* @see FlashMap * @see FlashMap
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -170,8 +170,8 @@ public abstract class RequestContextUtils {
/** /**
* Return the "output" FlashMap with attributes to save for a subsequent request. * Return the "output" FlashMap with attributes to save for a subsequent request.
* @param request current request * @param request the current request
* @return a {@link FlashMap} instance, never {@code null} * @return a {@link FlashMap} instance (never {@code null} within a DispatcherServlet request)
* @see FlashMap * @see FlashMap
*/ */
public static FlashMap getOutputFlashMap(HttpServletRequest request) { public static FlashMap getOutputFlashMap(HttpServletRequest request) {
@ -182,6 +182,7 @@ public abstract class RequestContextUtils {
* Return the FlashMapManager instance to save flash attributes with * Return the FlashMapManager instance to save flash attributes with
* before a redirect. * before a redirect.
* @param request the current request * @param request the current request
* @return a {@link FlashMapManager} instance (never {@code null} within a DispatcherServlet request)
*/ */
public static FlashMapManager getFlashMapManager(HttpServletRequest request) { public static FlashMapManager getFlashMapManager(HttpServletRequest request) {
return (FlashMapManager) request.getAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE); return (FlashMapManager) request.getAttribute(DispatcherServlet.FLASH_MAP_MANAGER_ATTRIBUTE);

49
spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -250,15 +249,15 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
return false; return false;
} }
/** /**
* Convert model to request parameters and redirect to the given URL. * Convert model to request parameters and redirect to the given URL.
* @see #appendQueryProperties * @see #appendQueryProperties
* @see #sendRedirect * @see #sendRedirect
*/ */
@Override @Override
protected void renderMergedOutputModel( protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) HttpServletResponse response) throws IOException {
throws IOException {
String targetUrl = createTargetUrl(model, request); String targetUrl = createTargetUrl(model, request);
targetUrl = updateTargetUrl(targetUrl, model, request, response); targetUrl = updateTargetUrl(targetUrl, model, request, response);
@ -268,11 +267,13 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build();
flashMap.setTargetRequestPath(uriComponents.getPath()); flashMap.setTargetRequestPath(uriComponents.getPath());
flashMap.addTargetRequestParams(uriComponents.getQueryParams()); flashMap.addTargetRequestParams(uriComponents.getQueryParams());
FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
if (flashMapManager == null) {
throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set");
}
flashMapManager.saveOutputFlashMap(flashMap, request, response);
} }
FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
flashMapManager.saveOutputFlashMap(flashMap, request, response);
sendRedirect(request, response, targetUrl, this.http10Compatible); sendRedirect(request, response, targetUrl, this.http10Compatible);
} }
@ -304,7 +305,6 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
Map<String, String> variables = getCurrentRequestUriVariables(request); Map<String, String> variables = getCurrentRequestUriVariables(request);
targetUrl = replaceUriTemplateVariables(targetUrl.toString(), model, variables, enc); targetUrl = replaceUriTemplateVariables(targetUrl.toString(), model, variables, enc);
} }
if (this.exposeModelAttributes) { if (this.exposeModelAttributes) {
appendQueryProperties(targetUrl, model, enc); appendQueryProperties(targetUrl, model, enc);
} }
@ -327,15 +327,17 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
Matcher m = URI_TEMPLATE_VARIABLE_PATTERN.matcher(targetUrl); Matcher matcher = URI_TEMPLATE_VARIABLE_PATTERN.matcher(targetUrl);
int endLastMatch = 0; int endLastMatch = 0;
while (m.find()) { while (matcher.find()) {
String name = m.group(1); String name = matcher.group(1);
Object value = model.containsKey(name) ? model.remove(name) : currentUriVariables.get(name); Object value = (model.containsKey(name) ? model.remove(name) : currentUriVariables.get(name));
Assert.notNull(value, "Model has no value for '" + name + "'"); if (value == null) {
result.append(targetUrl.substring(endLastMatch, m.start())); throw new IllegalArgumentException("Model has no value for key '" + name + "'");
}
result.append(targetUrl.substring(endLastMatch, matcher.start()));
result.append(UriUtils.encodePathSegment(value.toString(), encodingScheme)); result.append(UriUtils.encodePathSegment(value.toString(), encodingScheme));
endLastMatch = m.end(); endLastMatch = matcher.end();
} }
result.append(targetUrl.substring(endLastMatch, targetUrl.length())); result.append(targetUrl.substring(endLastMatch, targetUrl.length()));
return result; return result;
@ -344,7 +346,7 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<String, String> getCurrentRequestUriVariables(HttpServletRequest request) { private Map<String, String> getCurrentRequestUriVariables(HttpServletRequest request) {
Map<String, String> uriVars = Map<String, String> uriVars =
(Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
return (uriVars != null) ? uriVars : Collections.<String, String> emptyMap(); return (uriVars != null) ? uriVars : Collections.<String, String> emptyMap();
} }
@ -441,7 +443,6 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
if (isEligibleValue(value)) { if (isEligibleValue(value)) {
return true; return true;
} }
if (value.getClass().isArray()) { if (value.getClass().isArray()) {
int length = Array.getLength(value); int length = Array.getLength(value);
if (length == 0) { if (length == 0) {
@ -455,7 +456,6 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
} }
return true; return true;
} }
if (value instanceof Collection) { if (value instanceof Collection) {
Collection coll = (Collection) value; Collection coll = (Collection) value;
if (coll.isEmpty()) { if (coll.isEmpty()) {
@ -468,7 +468,6 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
} }
return true; return true;
} }
return false; return false;
} }
@ -504,7 +503,7 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
* @return the updated URL or the same as URL as the one passed in * @return the updated URL or the same as URL as the one passed in
*/ */
protected String updateTargetUrl(String targetUrl, Map<String, Object> model, protected String updateTargetUrl(String targetUrl, Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) { HttpServletRequest request, HttpServletResponse response) {
RequestContext requestContext = null; RequestContext requestContext = null;
if (getWebApplicationContext() != null) { if (getWebApplicationContext() != null) {
@ -516,14 +515,12 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
requestContext = new RequestContext(request, response, wac.getServletContext(), model); requestContext = new RequestContext(request, response, wac.getServletContext(), model);
} }
} }
if (requestContext != null) { if (requestContext != null) {
RequestDataValueProcessor processor = requestContext.getRequestDataValueProcessor(); RequestDataValueProcessor processor = requestContext.getRequestDataValueProcessor();
if (processor != null) { if (processor != null) {
targetUrl = processor.processUrl(request, targetUrl); targetUrl = processor.processUrl(request, targetUrl);
} }
} }
return targetUrl; return targetUrl;
} }
@ -535,12 +532,10 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
* @param http10Compatible whether to stay compatible with HTTP 1.0 clients * @param http10Compatible whether to stay compatible with HTTP 1.0 clients
* @throws IOException if thrown by response methods * @throws IOException if thrown by response methods
*/ */
protected void sendRedirect( protected void sendRedirect(HttpServletRequest request, HttpServletResponse response,
HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible) String targetUrl, boolean http10Compatible) throws IOException {
throws IOException {
String encodedRedirectURL = response.encodeRedirectURL(targetUrl); String encodedRedirectURL = response.encodeRedirectURL(targetUrl);
if (http10Compatible) { if (http10Compatible) {
if (this.statusCode != null) { if (this.statusCode != null) {
response.setStatus(this.statusCode.value()); response.setStatus(this.statusCode.value());

Loading…
Cancel
Save