diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/AbstractView.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/AbstractView.java index b6b8690800..5804d265ba 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/AbstractView.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/AbstractView.java @@ -256,6 +256,18 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement " and static attributes " + this.staticAttributes); } + Map mergedModel = createMergedOutputModel(model, request, response); + + prepareResponse(request, response); + renderMergedOutputModel(mergedModel, request, response); + } + + /** + * Creates a combined output Map (never null) that includes dynamic values and static attributes. + * Dynamic values take precedence over static attributes. + */ + protected Map createMergedOutputModel(Map model, HttpServletRequest request, + HttpServletResponse response) { @SuppressWarnings("unchecked") Map pathVars = this.exposePathVariables ? (Map) request.getAttribute(View.PATH_VARIABLES) : null; @@ -277,9 +289,8 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement if (this.requestContextAttribute != null) { mergedModel.put(this.requestContextAttribute, createRequestContext(request, response, mergedModel)); } - - prepareResponse(request, response); - renderMergedOutputModel(mergedModel, request, response); + + return mergedModel; } /** diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/RedirectView.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/RedirectView.java index e35cd532a4..0a3f5893ef 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/RedirectView.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/RedirectView.java @@ -38,7 +38,6 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.http.HttpStatus; import org.springframework.util.ObjectUtils; -import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.View; import org.springframework.web.util.UriTemplate; import org.springframework.web.util.UriUtils; @@ -46,10 +45,13 @@ import org.springframework.web.util.WebUtils; /** *

View that redirects to an absolute, context relative, or current request - * relative URL. By default all primitive model attributes (or collections - * thereof) are exposed as HTTP query parameters, but this behavior can be changed - * by overriding the {@link #isEligibleProperty(String, Object)} method. - * + * relative URL. The URL may be a URI template in which case the URI template + * variables will be replaced with values available in the model. By default + * all primitive model attributes (or collections thereof), not used to fill + * in URI tempate variables, are exposed as HTTP query parameters, but this + * behavior can be changed by overriding the + * {@link #isEligibleProperty(String, Object)} method. + * *

A URL for this view is supposed to be a HTTP redirect URL, i.e. * suitable for HttpServletResponse's sendRedirect method, which * is what actually does the redirect if the HTTP 1.0 flag is on, or via sending @@ -215,7 +217,18 @@ public class RedirectView extends AbstractUrlBasedView { protected void renderMergedOutputModel( Map model, HttpServletRequest request, HttpServletResponse response) throws IOException { + String targetUrl = createTargetUrl(model, request); + sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); + } + /** + * Creates the target URL by checking if the redirect string is a URI template first, + * expanding it with the given model, and then optionally appending simple type model + * attributes as query String parameters. + */ + protected final String createTargetUrl(Map model, HttpServletRequest request) + throws UnsupportedEncodingException { + // Prepare target URL. StringBuilder targetUrl = new StringBuilder(); if (this.contextRelative && getUrl().startsWith("/")) { @@ -237,6 +250,7 @@ public class RedirectView extends AbstractUrlBasedView { targetUrl = new StringBuilder(redirectUri.expand(model).toString()); model = removeKeys(model, redirectUri.getVariableNames()); } + if (this.exposeModelAttributes) { List pathVarNames = getPathVarNames(request); if (!pathVarNames.isEmpty()) { @@ -244,8 +258,8 @@ public class RedirectView extends AbstractUrlBasedView { } appendQueryProperties(targetUrl, model, enc); } - - sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); + + return targetUrl.toString(); } @SuppressWarnings("serial") @@ -278,8 +292,7 @@ public class RedirectView extends AbstractUrlBasedView { */ @SuppressWarnings("unchecked") private List getPathVarNames(HttpServletRequest request) { - String key = View.PATH_VARIABLES; - Map map = (Map) request.getAttribute(key); + Map map = (Map) request.getAttribute(View.PATH_VARIABLES); return (map != null) ? new ArrayList(map.keySet()) : Collections.emptyList(); }