|
|
|
@ -19,6 +19,7 @@ package org.springframework.web.servlet.view; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
import java.lang.reflect.Array; |
|
|
|
import java.lang.reflect.Array; |
|
|
|
|
|
|
|
import java.net.URLEncoder; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
@ -32,7 +33,6 @@ import org.springframework.beans.BeanUtils; |
|
|
|
import org.springframework.http.HttpStatus; |
|
|
|
import org.springframework.http.HttpStatus; |
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
import org.springframework.web.util.UriUtils; |
|
|
|
|
|
|
|
import org.springframework.web.util.WebUtils; |
|
|
|
import org.springframework.web.util.WebUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -207,36 +207,27 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) |
|
|
|
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
String encoding = getEncoding(request); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare target URL.
|
|
|
|
// Prepare target URL.
|
|
|
|
StringBuilder targetUrl = new StringBuilder(); |
|
|
|
StringBuilder targetUrl = new StringBuilder(); |
|
|
|
if (this.contextRelative && getUrl().startsWith("/")) { |
|
|
|
if (this.contextRelative && getUrl().startsWith("/")) { |
|
|
|
// Do not apply context path to relative URLs.
|
|
|
|
// Do not apply context path to relative URLs.
|
|
|
|
targetUrl.append(UriUtils.encodePath(request.getContextPath(), encoding)); |
|
|
|
targetUrl.append(request.getContextPath()); |
|
|
|
targetUrl.append(UriUtils.encodeUri(getUrl(), encoding)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
targetUrl.append(UriUtils.encodeUri(getUrl(), encoding)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
targetUrl.append(getUrl()); |
|
|
|
if (this.exposeModelAttributes) { |
|
|
|
if (this.exposeModelAttributes) { |
|
|
|
appendQueryProperties(targetUrl, model, encoding); |
|
|
|
String enc = this.encodingScheme; |
|
|
|
|
|
|
|
if (enc == null) { |
|
|
|
|
|
|
|
enc = request.getCharacterEncoding(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (enc == null) { |
|
|
|
|
|
|
|
enc = WebUtils.DEFAULT_CHARACTER_ENCODING; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
appendQueryProperties(targetUrl, model, enc); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); |
|
|
|
sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String getEncoding(HttpServletRequest request) { |
|
|
|
|
|
|
|
String enc = this.encodingScheme; |
|
|
|
|
|
|
|
if (enc == null) { |
|
|
|
|
|
|
|
enc = request.getCharacterEncoding(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (enc == null) { |
|
|
|
|
|
|
|
enc = WebUtils.DEFAULT_CHARACTER_ENCODING; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return enc; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Append query properties to the redirect URL. |
|
|
|
* Append query properties to the redirect URL. |
|
|
|
* Stringifies, URL-encodes and formats model attributes as query properties. |
|
|
|
* Stringifies, URL-encodes and formats model attributes as query properties. |
|
|
|
@ -261,7 +252,7 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
boolean first = (getUrl().indexOf('?') < 0); |
|
|
|
boolean first = (getUrl().indexOf('?') < 0); |
|
|
|
for (Map.Entry<String, Object> entry : queryProperties(model).entrySet()) { |
|
|
|
for (Map.Entry<String, Object> entry : queryProperties(model).entrySet()) { |
|
|
|
Object rawValue = entry.getValue(); |
|
|
|
Object rawValue = entry.getValue(); |
|
|
|
Iterator valueIter; |
|
|
|
Iterator valueIter = null; |
|
|
|
if (rawValue != null && rawValue.getClass().isArray()) { |
|
|
|
if (rawValue != null && rawValue.getClass().isArray()) { |
|
|
|
valueIter = Arrays.asList(ObjectUtils.toObjectArray(rawValue)).iterator(); |
|
|
|
valueIter = Arrays.asList(ObjectUtils.toObjectArray(rawValue)).iterator(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -280,8 +271,8 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
else { |
|
|
|
else { |
|
|
|
targetUrl.append('&'); |
|
|
|
targetUrl.append('&'); |
|
|
|
} |
|
|
|
} |
|
|
|
String encodedKey = UriUtils.encodeQueryParam(entry.getKey(), encodingScheme); |
|
|
|
String encodedKey = urlEncode(entry.getKey(), encodingScheme); |
|
|
|
String encodedValue = (value != null ? UriUtils.encodeQueryParam(value.toString(), encodingScheme) : ""); |
|
|
|
String encodedValue = (value != null ? urlEncode(value.toString(), encodingScheme) : ""); |
|
|
|
targetUrl.append(encodedKey).append('=').append(encodedValue); |
|
|
|
targetUrl.append(encodedKey).append('=').append(encodedValue); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -289,7 +280,7 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
// Append anchor fragment, if any, to end of URL.
|
|
|
|
// Append anchor fragment, if any, to end of URL.
|
|
|
|
if (fragment != null) { |
|
|
|
if (fragment != null) { |
|
|
|
targetUrl.append(fragment); |
|
|
|
targetUrl.append(fragment); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -372,6 +363,20 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
return (value != null && BeanUtils.isSimpleValueType(value.getClass())); |
|
|
|
return (value != null && BeanUtils.isSimpleValueType(value.getClass())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* URL-encode the given input String with the given encoding scheme. |
|
|
|
|
|
|
|
* <p>The default implementation uses <code>URLEncoder.encode(input, enc)</code>. |
|
|
|
|
|
|
|
* @param input the unencoded input String |
|
|
|
|
|
|
|
* @param encodingScheme the encoding scheme |
|
|
|
|
|
|
|
* @return the encoded output String |
|
|
|
|
|
|
|
* @throws UnsupportedEncodingException if thrown by the JDK URLEncoder |
|
|
|
|
|
|
|
* @see java.net.URLEncoder#encode(String, String) |
|
|
|
|
|
|
|
* @see java.net.URLEncoder#encode(String) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected String urlEncode(String input, String encodingScheme) throws UnsupportedEncodingException { |
|
|
|
|
|
|
|
return (input != null ? URLEncoder.encode(input, encodingScheme) : null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Send a redirect back to the HTTP client |
|
|
|
* Send a redirect back to the HTTP client |
|
|
|
* @param request current HTTP request (allows for reacting to request method) |
|
|
|
* @param request current HTTP request (allows for reacting to request method) |
|
|
|
@ -398,18 +403,14 @@ public class RedirectView extends AbstractUrlBasedView { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Determines the status code to use for HTTP 1.1 compatible requests. |
|
|
|
* Determines the status code to use for HTTP 1.1 compatible requests. |
|
|
|
* <p>The default implemenetation returns the {@link #setStatusCode(HttpStatus) statusCode} |
|
|
|
* <p>The default implemenetation returns the {@link #setStatusCode(HttpStatus) statusCode} |
|
|
|
* property if set, or the value of the {@link #RESPONSE_STATUS_ATTRIBUTE} attribute. |
|
|
|
* property if set, or the value of the {@link #RESPONSE_STATUS_ATTRIBUTE} attribute. If neither are |
|
|
|
* If neither are set, it defaults to {@link HttpStatus#SEE_OTHER} (303). |
|
|
|
* set, it defaults to {@link HttpStatus#SEE_OTHER} (303). |
|
|
|
* @param request the request to inspect |
|
|
|
* @param request the request to inspect |
|
|
|
* @param response the servlet response |
|
|
|
* @return the response |
|
|
|
* @param targetUrl the target URL |
|
|
|
|
|
|
|
* @return the response status |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected HttpStatus getHttp11StatusCode( |
|
|
|
protected HttpStatus getHttp11StatusCode(HttpServletRequest request, HttpServletResponse response, String targetUrl) { |
|
|
|
HttpServletRequest request, HttpServletResponse response, String targetUrl) { |
|
|
|
if (statusCode != null) { |
|
|
|
|
|
|
|
return statusCode; |
|
|
|
if (this.statusCode != null) { |
|
|
|
|
|
|
|
return this.statusCode; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE); |
|
|
|
HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE); |
|
|
|
if (attributeStatusCode != null) { |
|
|
|
if (attributeStatusCode != null) { |
|
|
|
|