|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2013 the original author or authors. |
| 2 | + * Copyright 2002-2014 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
53 | 53 | import org.springframework.web.util.WebUtils;
|
54 | 54 |
|
55 | 55 | /**
|
56 |
| - * <p>View that redirects to an absolute, context relative, or current request |
| 56 | + * View that redirects to an absolute, context relative, or current request |
57 | 57 | * relative URL. The URL may be a URI template in which case the URI template
|
58 | 58 | * variables will be replaced with values available in the model. By default
|
59 | 59 | * all primitive model attributes (or collections thereof) are exposed as HTTP
|
@@ -105,6 +105,8 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
|
105 | 105 |
|
106 | 106 | private boolean expandUriTemplateVariables = true;
|
107 | 107 |
|
| 108 | + private boolean propagateQueryParams = false; |
| 109 | + |
108 | 110 |
|
109 | 111 | /**
|
110 | 112 | * Constructor for use as a bean.
|
@@ -235,6 +237,24 @@ public void setExpandUriTemplateVariables(boolean expandUriTemplateVariables) {
|
235 | 237 | this.expandUriTemplateVariables = expandUriTemplateVariables;
|
236 | 238 | }
|
237 | 239 |
|
| 240 | + /** |
| 241 | + * When set to {@code true} the query string of the current URL is appended |
| 242 | + * and thus propagated through to the redirected URL. |
| 243 | + * <p>Defaults to {@code false}. |
| 244 | + * @since 4.1 |
| 245 | + */ |
| 246 | + public void setPropagateQueryParams(boolean propagateQueryParams) { |
| 247 | + this.propagateQueryParams = propagateQueryParams; |
| 248 | + } |
| 249 | + |
| 250 | + /** |
| 251 | + * Whether to propagate the query params of the current URL. |
| 252 | + * @since 4.1 |
| 253 | + */ |
| 254 | + public boolean isPropagateQueryProperties() { |
| 255 | + return this.propagateQueryParams; |
| 256 | + } |
| 257 | + |
238 | 258 | /**
|
239 | 259 | * Returns "true" indicating this view performs a redirect.
|
240 | 260 | */
|
@@ -307,6 +327,9 @@ protected final String createTargetUrl(Map<String, Object> model, HttpServletReq
|
307 | 327 | Map<String, String> variables = getCurrentRequestUriVariables(request);
|
308 | 328 | targetUrl = replaceUriTemplateVariables(targetUrl.toString(), model, variables, enc);
|
309 | 329 | }
|
| 330 | + if (isPropagateQueryProperties()) { |
| 331 | + appendCurrentQueryParams(targetUrl, request); |
| 332 | + } |
310 | 333 | if (this.exposeModelAttributes) {
|
311 | 334 | appendQueryProperties(targetUrl, model, enc);
|
312 | 335 | }
|
@@ -347,11 +370,44 @@ protected StringBuilder replaceUriTemplateVariables(
|
347 | 370 |
|
348 | 371 | @SuppressWarnings("unchecked")
|
349 | 372 | private Map<String, String> getCurrentRequestUriVariables(HttpServletRequest request) {
|
350 |
| - Map<String, String> uriVars = |
351 |
| - (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); |
| 373 | + String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE; |
| 374 | + Map<String, String> uriVars = (Map<String, String>) request.getAttribute(name); |
352 | 375 | return (uriVars != null) ? uriVars : Collections.<String, String> emptyMap();
|
353 | 376 | }
|
354 | 377 |
|
| 378 | + /** |
| 379 | + * Append the query string of the current request to the target redirect URL. |
| 380 | + * @param targetUrl the StringBuilder to append the properties to |
| 381 | + * @param request the current request |
| 382 | + * @since 4.1 |
| 383 | + */ |
| 384 | + protected void appendCurrentQueryParams(StringBuilder targetUrl, HttpServletRequest request) { |
| 385 | + |
| 386 | + String query = request.getQueryString(); |
| 387 | + if (StringUtils.hasText(query)) { |
| 388 | + |
| 389 | + // Extract anchor fragment, if any. |
| 390 | + String fragment = null; |
| 391 | + int anchorIndex = targetUrl.indexOf("#"); |
| 392 | + if (anchorIndex > -1) { |
| 393 | + fragment = targetUrl.substring(anchorIndex); |
| 394 | + targetUrl.delete(anchorIndex, targetUrl.length()); |
| 395 | + } |
| 396 | + |
| 397 | + if (targetUrl.toString().indexOf('?') < 0) { |
| 398 | + targetUrl.append('?').append(query); |
| 399 | + } |
| 400 | + else { |
| 401 | + targetUrl.append('&').append(query); |
| 402 | + } |
| 403 | + |
| 404 | + // Append anchor fragment, if any, to end of URL. |
| 405 | + if (fragment != null) { |
| 406 | + targetUrl.append(fragment); |
| 407 | + } |
| 408 | + } |
| 409 | + } |
| 410 | + |
355 | 411 | /**
|
356 | 412 | * Append query properties to the redirect URL.
|
357 | 413 | * Stringifies, URL-encodes and formats model attributes as query properties.
|
|
0 commit comments