diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java
index 1db7aafb831..8a74f778afc 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -53,7 +53,7 @@ import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;
/**
- *
View that redirects to an absolute, context relative, or current request
+ * View that redirects to an absolute, context relative, or current request
* 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) are exposed as HTTP
@@ -105,6 +105,8 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
private boolean expandUriTemplateVariables = true;
+ private boolean propagateQueryParams = false;
+
/**
* Constructor for use as a bean.
@@ -235,6 +237,24 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
this.expandUriTemplateVariables = expandUriTemplateVariables;
}
+ /**
+ * When set to {@code true} the query string of the current URL is appended
+ * and thus propagated through to the redirected URL.
+ *
Defaults to {@code false}.
+ * @since 4.1
+ */
+ public void setPropagateQueryParams(boolean propagateQueryParams) {
+ this.propagateQueryParams = propagateQueryParams;
+ }
+
+ /**
+ * Whether to propagate the query params of the current URL.
+ * @since 4.1
+ */
+ public boolean isPropagateQueryProperties() {
+ return this.propagateQueryParams;
+ }
+
/**
* Returns "true" indicating this view performs a redirect.
*/
@@ -307,6 +327,9 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
Map variables = getCurrentRequestUriVariables(request);
targetUrl = replaceUriTemplateVariables(targetUrl.toString(), model, variables, enc);
}
+ if (isPropagateQueryProperties()) {
+ appendCurrentQueryParams(targetUrl, request);
+ }
if (this.exposeModelAttributes) {
appendQueryProperties(targetUrl, model, enc);
}
@@ -347,11 +370,44 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
@SuppressWarnings("unchecked")
private Map getCurrentRequestUriVariables(HttpServletRequest request) {
- Map uriVars =
- (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+ String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
+ Map uriVars = (Map) request.getAttribute(name);
return (uriVars != null) ? uriVars : Collections. emptyMap();
}
+ /**
+ * Append the query string of the current request to the target redirect URL.
+ * @param targetUrl the StringBuilder to append the properties to
+ * @param request the current request
+ * @since 4.1
+ */
+ protected void appendCurrentQueryParams(StringBuilder targetUrl, HttpServletRequest request) {
+
+ String query = request.getQueryString();
+ if (StringUtils.hasText(query)) {
+
+ // Extract anchor fragment, if any.
+ String fragment = null;
+ int anchorIndex = targetUrl.indexOf("#");
+ if (anchorIndex > -1) {
+ fragment = targetUrl.substring(anchorIndex);
+ targetUrl.delete(anchorIndex, targetUrl.length());
+ }
+
+ if (targetUrl.toString().indexOf('?') < 0) {
+ targetUrl.append('?').append(query);
+ }
+ else {
+ targetUrl.append('&').append(query);
+ }
+
+ // Append anchor fragment, if any, to end of URL.
+ if (fragment != null) {
+ targetUrl.append(fragment);
+ }
+ }
+ }
+
/**
* Append query properties to the redirect URL.
* Stringifies, URL-encodes and formats model attributes as query properties.
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java
index 2e800c9d5b8..3b142aca481 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java
@@ -325,6 +325,19 @@ public class RedirectViewTests {
doTest(model, url, false, expectedUrlForEncoding);
}
+ @Test
+ public void propagateQueryParams() throws Exception {
+ RedirectView rv = new RedirectView();
+ rv.setPropagateQueryParams(true);
+ rv.setUrl("http://url.somewhere.com?foo=bar#bazz");
+ MockHttpServletRequest request = createRequest();
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ request.setQueryString("a=b&c=d");
+ rv.render(new HashMap(), request, response);
+ assertEquals(302, response.getStatus());
+ assertEquals("http://url.somewhere.com?foo=bar&a=b&c=d#bazz", response.getHeader("Location"));
+ }
+
private void doTest(Map map, String url, boolean contextRelative, String expectedUrlForEncoding)
throws Exception {
doTest(map, url, contextRelative, true, expectedUrlForEncoding);