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 05d3c3347d6..396157c50a2 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 @@ -22,6 +22,7 @@ import java.lang.reflect.Array; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -30,15 +31,14 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.BeanUtils; import org.springframework.http.HttpStatus; -import org.springframework.ui.Model; 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; @@ -232,18 +232,23 @@ public class RedirectView extends AbstractUrlBasedView { enc = WebUtils.DEFAULT_CHARACTER_ENCODING; } - UriTemplate uriTemplate = createUriTemplate(targetUrl, enc); - if (uriTemplate.getVariableNames().size() > 0) { - targetUrl = new StringBuilder(uriTemplate.expand(model).toString()); - model = removeKeys(model, uriTemplate.getVariableNames()); + UriTemplate redirectUri = createUriTemplate(targetUrl, enc); + if (redirectUri.getVariableNames().size() > 0) { + targetUrl = new StringBuilder(redirectUri.expand(model).toString()); + model = removeKeys(model, redirectUri.getVariableNames()); } if (this.exposeModelAttributes) { + List uriTemplateVarNames = getUriTemplateVarNames(request); + if (!uriTemplateVarNames.isEmpty()) { + model = removeKeys(model, uriTemplateVarNames); + } appendQueryProperties(targetUrl, model, enc); } sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); } + @SuppressWarnings("serial") private UriTemplate createUriTemplate(StringBuilder targetUrl, final String encoding) { return new UriTemplate(targetUrl.toString()) { @Override @@ -268,6 +273,16 @@ public class RedirectView extends AbstractUrlBasedView { return result; } + /** + * Returns URI template variable names for the current request; or an empty list. + */ + @SuppressWarnings("unchecked") + private List getUriTemplateVarNames(HttpServletRequest request) { + String key = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE; + Map map = (Map) request.getAttribute(key); + return (map != null) ? new ArrayList(map.keySet()) : Collections.emptyList(); + } + /** * Append query properties to the redirect URL. * Stringifies, URL-encodes and formats model attributes as query properties. diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/RedirectViewUriTemplateTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/RedirectViewUriTemplateTests.java index 684768700c5..2279c7b8492 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/RedirectViewUriTemplateTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/RedirectViewUriTemplateTests.java @@ -25,6 +25,7 @@ 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.HandlerMapping; public class RedirectViewUriTemplateTests { @@ -39,7 +40,7 @@ public class RedirectViewUriTemplateTests { } @Test - public void pathVar() throws Exception { + public void uriTemplateVar() throws Exception { Map model = new HashMap(); model.put("foo", "bar"); @@ -51,7 +52,7 @@ public class RedirectViewUriTemplateTests { } @Test - public void pathVarAndArrayParam() throws Exception { + public void uriTemplateVarAndArrayParam() throws Exception { Map model = new HashMap(); model.put("foo", "bar"); model.put("fooArr", new String[] { "baz", "bazz" }); @@ -63,7 +64,7 @@ public class RedirectViewUriTemplateTests { } @Test - public void pathVarWithObjectConversion() throws Exception { + public void uriTemplateVarWithObjectConversion() throws Exception { Map model = new HashMap(); model.put("foo", new Long(611)); @@ -73,4 +74,22 @@ public class RedirectViewUriTemplateTests { assertEquals("/foo/611", response.getRedirectedUrl()); } + @Test + public void doNotAppendUriTemplateVarFromCurrentRequest() throws Exception { + Map model = new HashMap(); + model.put("name1", "value1"); + model.put("name2", "value2"); + model.put("name3", "value3"); + + Map uriTemplatVars = new HashMap(); + uriTemplatVars.put("name1", "value1"); + uriTemplatVars.put("name2", "value2"); + request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplatVars); + + String url = "http://url.somewhere.com"; + RedirectView redirectView = new RedirectView(url + "/{name2}"); + redirectView.renderMergedOutputModel(model, request, response); + + assertEquals(url + "/value2?name3=value3", response.getRedirectedUrl()); + } }