ServletResponseHttpHeaders consistently overrides HttpHeaders again
Issue: SPR-14406
This commit is contained in:
@@ -58,6 +58,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Arjen Poutsma
|
||||
* @author Sebastien Deleuze
|
||||
* @author Brian Clozel
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
|
||||
@@ -454,7 +455,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
* Returns the value of the {@code Access-Control-Allow-Credentials} response header.
|
||||
*/
|
||||
public boolean getAccessControlAllowCredentials() {
|
||||
return new Boolean(getFirst(ACCESS_CONTROL_ALLOW_CREDENTIALS));
|
||||
return Boolean.parseBoolean(getFirst(ACCESS_CONTROL_ALLOW_CREDENTIALS));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,22 +511,6 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
return getFieldValues(ACCESS_CONTROL_ALLOW_ORIGIN);
|
||||
}
|
||||
|
||||
protected String getFieldValues(String headerName) {
|
||||
List<String> headerValues = this.headers.get(headerName);
|
||||
if (headerValues != null) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<String> iterator = headerValues.iterator(); iterator.hasNext(); ) {
|
||||
String ifNoneMatch = iterator.next();
|
||||
builder.append(ifNoneMatch);
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(", ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code Access-Control-Expose-Headers} response header.
|
||||
*/
|
||||
@@ -809,6 +794,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code If-Match} header.
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setIfMatch(String ifMatch) {
|
||||
set(IF_MATCH, ifMatch);
|
||||
@@ -816,55 +802,20 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code If-Match} header.
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setIfMatch(List<String> ifMatchList) {
|
||||
set(IF_MATCH, toCommaDelimitedString(ifMatchList));
|
||||
}
|
||||
|
||||
protected String toCommaDelimitedString(List<String> list) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
|
||||
String ifNoneMatch = iterator.next();
|
||||
builder.append(ifNoneMatch);
|
||||
if (iterator.hasNext()) {
|
||||
builder.append(", ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the {@code If-Match} header.
|
||||
* @since 4.3
|
||||
*/
|
||||
public List<String> getIfMatch() {
|
||||
return getETagValuesAsList(IF_MATCH);
|
||||
}
|
||||
|
||||
protected List<String> getETagValuesAsList(String headerName) {
|
||||
List<String> values = get(headerName);
|
||||
if (values != null) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String value : values) {
|
||||
if (value != null) {
|
||||
Matcher matcher = ETAG_HEADER_VALUE_PATTERN.matcher(value);
|
||||
while (matcher.find()) {
|
||||
if ("*".equals(matcher.group())) {
|
||||
result.add(matcher.group());
|
||||
}
|
||||
else {
|
||||
result.add(matcher.group(1));
|
||||
}
|
||||
}
|
||||
if(result.size() == 0) {
|
||||
throw new IllegalArgumentException("Could not parse '" + headerName + "' value=" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code If-Modified-Since} header.
|
||||
* <p>The date should be specified as the number of milliseconds since
|
||||
@@ -904,32 +855,11 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
return getETagValuesAsList(IF_NONE_MATCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all values of a given header name,
|
||||
* even if this header is set multiple times.
|
||||
* @since 4.3
|
||||
*/
|
||||
public List<String> getValuesAsList(String headerName) {
|
||||
List<String> values = get(headerName);
|
||||
if (values != null) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String value : values) {
|
||||
if (value != null) {
|
||||
String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
|
||||
for (String token : tokens) {
|
||||
result.add(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code If-Unmodified-Since} header.
|
||||
* <p>The date should be specified as the number of milliseconds since
|
||||
* January 1, 1970 GMT.
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setIfUnmodifiedSince(long ifUnmodifiedSince) {
|
||||
setDate(IF_UNMODIFIED_SINCE, ifUnmodifiedSince);
|
||||
@@ -939,6 +869,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
* Return the value of the {@code If-Unmodified-Since} header.
|
||||
* <p>The date is returned as the number of milliseconds since
|
||||
* January 1, 1970 GMT. Returns -1 when the date is unknown.
|
||||
* @since 4.3
|
||||
*/
|
||||
public long getIfUnmodifiedSince() {
|
||||
return getFirstDate(IF_UNMODIFIED_SINCE, false);
|
||||
@@ -1054,17 +985,31 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
|
||||
/**
|
||||
* Return the request header names subject to content negotiation.
|
||||
* @since 4.3
|
||||
*/
|
||||
public List<String> getVary() {
|
||||
return getValuesAsList(VARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given date under the given header name after formatting it as a string
|
||||
* using the pattern {@code "EEE, dd MMM yyyy HH:mm:ss zzz"}. The equivalent of
|
||||
* {@link #set(String, String)} but for date headers.
|
||||
* @since 3.2.4
|
||||
*/
|
||||
public void setDate(String headerName, long date) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMATS[0], Locale.US);
|
||||
dateFormat.setTimeZone(GMT);
|
||||
set(headerName, dateFormat.format(new Date(date)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first header value for the given header name as a date,
|
||||
* return -1 if there is no value, or raise {@link IllegalArgumentException}
|
||||
* if the value cannot be parsed as a date.
|
||||
* @param headerName the header name
|
||||
* @return the parsed date header, or -1 if none
|
||||
* @since 3.2.4
|
||||
*/
|
||||
public long getFirstDate(String headerName) {
|
||||
return getFirstDate(headerName, true);
|
||||
@@ -1109,16 +1054,92 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given date under the given header name after formatting it as a string
|
||||
* using the pattern {@code "EEE, dd MMM yyyy HH:mm:ss zzz"}. The equivalent of
|
||||
* {@link #set(String, String)} but for date headers.
|
||||
* Return all values of a given header name,
|
||||
* even if this header is set multiple times.
|
||||
* @param headerName the header name
|
||||
* @return all associated values
|
||||
* @since 4.3
|
||||
*/
|
||||
public void setDate(String headerName, long date) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMATS[0], Locale.US);
|
||||
dateFormat.setTimeZone(GMT);
|
||||
set(headerName, dateFormat.format(new Date(date)));
|
||||
public List<String> getValuesAsList(String headerName) {
|
||||
List<String> values = get(headerName);
|
||||
if (values != null) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String value : values) {
|
||||
if (value != null) {
|
||||
String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
|
||||
for (String token : tokens) {
|
||||
result.add(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a combined result from the field values of the ETag header.
|
||||
* @param headerName the header name
|
||||
* @return the combined result
|
||||
* @since 4.3
|
||||
*/
|
||||
protected List<String> getETagValuesAsList(String headerName) {
|
||||
List<String> values = get(headerName);
|
||||
if (values != null) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String value : values) {
|
||||
if (value != null) {
|
||||
Matcher matcher = ETAG_HEADER_VALUE_PATTERN.matcher(value);
|
||||
while (matcher.find()) {
|
||||
if ("*".equals(matcher.group())) {
|
||||
result.add(matcher.group());
|
||||
}
|
||||
else {
|
||||
result.add(matcher.group(1));
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not parse header '" + headerName + "' with value '" + value + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a combined result from the field values of multi-valued headers.
|
||||
* @param headerName the header name
|
||||
* @return the combined result
|
||||
* @since 4.3
|
||||
*/
|
||||
protected String getFieldValues(String headerName) {
|
||||
List<String> headerValues = get(headerName);
|
||||
return (headerValues != null ? toCommaDelimitedString(headerValues) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the given list of header values into a comma-delimited result.
|
||||
* @param headerValues the list of header values
|
||||
* @return a combined result with comma delimitation
|
||||
*/
|
||||
protected String toCommaDelimitedString(List<String> headerValues) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Iterator<String> it = headerValues.iterator(); it.hasNext(); ) {
|
||||
String val = it.next();
|
||||
builder.append(val);
|
||||
if (it.hasNext()) {
|
||||
builder.append(", ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
// MultiValueMap implementation
|
||||
|
||||
/**
|
||||
* Return the first header value for the given header name, if any.
|
||||
* @param headerName the header name
|
||||
|
||||
Reference in New Issue
Block a user