Overloaded convenience setters: setCacheControl(CacheControl), setExpires(ZonedDateTime)
Issue: SPR-16562
This commit is contained in:
parent
82515a3f01
commit
90d768bb7f
|
@ -48,7 +48,6 @@ import org.springframework.util.LinkedCaseInsensitiveMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Represents HTTP request and response headers, mapping string header names to a list of string values.
|
||||
*
|
||||
|
@ -472,8 +471,8 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
* {@link #getAcceptLanguageAsLocales()} or if you need to filter based on
|
||||
* a list of supported locales you can pass the returned list to
|
||||
* {@link Locale#filter(List, Collection)}.
|
||||
* @since 5.0
|
||||
* @throws IllegalArgumentException if the value cannot be converted to a language range
|
||||
* @since 5.0
|
||||
*/
|
||||
public List<Locale.LanguageRange> getAcceptLanguage() {
|
||||
String value = getFirst(ACCEPT_LANGUAGE);
|
||||
|
@ -494,8 +493,8 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
* A variant of {@link #getAcceptLanguage()} that converts each
|
||||
* {@link java.util.Locale.LanguageRange} to a {@link Locale}.
|
||||
* @return the locales or an empty list
|
||||
* @since 5.0
|
||||
* @throws IllegalArgumentException if the value cannot be converted to a locale
|
||||
* @since 5.0
|
||||
*/
|
||||
public List<Locale> getAcceptLanguageAsLocales() {
|
||||
List<Locale.LanguageRange> ranges = getAcceptLanguage();
|
||||
|
@ -711,6 +710,15 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a configured {@link CacheControl} instance as the
|
||||
* new value of the {@code Cache-Control} header.
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public void setCacheControl(CacheControl cacheControl) {
|
||||
set(CACHE_CONTROL, cacheControl.getHeaderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the (new) value of the {@code Cache-Control} header.
|
||||
*/
|
||||
|
@ -907,6 +915,15 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
return getFirst(ETAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration after which the message is no longer valid,
|
||||
* as specified by the {@code Expires} header.
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public void setExpires(ZonedDateTime expires) {
|
||||
setZonedDateTime(EXPIRES, expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the date and time at which the message is no longer valid,
|
||||
* as specified by the {@code Expires} header.
|
||||
|
@ -932,13 +949,16 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
* Set the (new) value of the {@code Host} header.
|
||||
* <p>If the given {@linkplain InetSocketAddress#getPort() port} is {@code 0},
|
||||
* the host header will only contain the
|
||||
* {@linkplain InetSocketAddress#getHostString() hostname}.
|
||||
* {@linkplain InetSocketAddress#getHostString() host name}.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setHost(@Nullable InetSocketAddress host) {
|
||||
if (host != null) {
|
||||
String value = (host.getPort() != 0 ?
|
||||
String.format("%s:%d", host.getHostString(), host.getPort()) : host.getHostString());
|
||||
String value = host.getHostString();
|
||||
int port = host.getPort();
|
||||
if (port != 0) {
|
||||
value = value + ":" + port;
|
||||
}
|
||||
set(HOST, value);
|
||||
}
|
||||
else {
|
||||
|
@ -958,28 +978,25 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
final int idx;
|
||||
if (value.startsWith("[")) {
|
||||
idx = value.indexOf(':', value.indexOf(']'));
|
||||
} else {
|
||||
idx = value.lastIndexOf(':');
|
||||
}
|
||||
String hostname = null;
|
||||
|
||||
String host = null;
|
||||
int port = 0;
|
||||
if (idx != -1 && idx < value.length() - 1) {
|
||||
hostname = value.substring(0, idx);
|
||||
String portString = value.substring(idx + 1);
|
||||
int separator = (value.startsWith("[") ? value.indexOf(':', value.indexOf(']')) : value.lastIndexOf(':'));
|
||||
if (separator != -1) {
|
||||
host = value.substring(0, separator);
|
||||
String portString = value.substring(separator + 1);
|
||||
try {
|
||||
port = Integer.parseInt(portString);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
// ignored
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (hostname == null) {
|
||||
hostname = value;
|
||||
|
||||
if (host == null) {
|
||||
host = value;
|
||||
}
|
||||
return InetSocketAddress.createUnresolved(hostname, port);
|
||||
return InetSocketAddress.createUnresolved(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1188,6 +1205,16 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
return getValuesAsList(VARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given date under the given header name after formatting it as a string
|
||||
* using the RFC-1123 date-time formatter. The equivalent of
|
||||
* {@link #set(String, String)} but for date headers.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setZonedDateTime(String headerName, ZonedDateTime date) {
|
||||
set(headerName, DATE_FORMATTERS[0].format(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given date under the given header name after formatting it as a string
|
||||
* using the RFC-1123 date-time formatter. The equivalent of
|
||||
|
@ -1201,16 +1228,6 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
set(headerName, DATE_FORMATTERS[0].format(zonedDateTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given date under the given header name after formatting it as a string
|
||||
* using the RFC-1123 date-time formatter. The equivalent of
|
||||
* {@link #set(String, String)} but for date headers.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setZonedDateTime(String headerName, ZonedDateTime date) {
|
||||
set(headerName, DATE_FORMATTERS[0].format(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}
|
||||
|
@ -1549,7 +1566,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
* Return a {@code HttpHeaders} object that can only be read, not written to.
|
||||
*/
|
||||
public static HttpHeaders readOnlyHttpHeaders(HttpHeaders headers) {
|
||||
return headers.readOnly ? headers : new HttpHeaders(headers, true);
|
||||
return (headers.readOnly ? headers : new HttpHeaders(headers, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
|
@ -21,6 +21,7 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
@ -37,13 +38,8 @@ import org.hamcrest.Matchers;
|
|||
import org.junit.Test;
|
||||
|
||||
import static java.time.format.DateTimeFormatter.*;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.http.HttpHeaders}.
|
||||
|
@ -51,6 +47,7 @@ import static org.junit.Assert.assertTrue;
|
|||
* @author Arjen Poutsma
|
||||
* @author Sebastien Deleuze
|
||||
* @author Brian Clozel
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class HttpHeadersTests {
|
||||
|
||||
|
@ -284,7 +281,7 @@ public class HttpHeadersTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void expires() {
|
||||
public void expiresLong() {
|
||||
Calendar calendar = new GregorianCalendar(2008, 11, 18, 11, 20);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("CET"));
|
||||
long date = calendar.getTimeInMillis();
|
||||
|
@ -293,6 +290,19 @@ public class HttpHeadersTests {
|
|||
assertEquals("Invalid Expires header", "Thu, 18 Dec 2008 10:20:00 GMT", headers.getFirst("expires"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expiresZonedDateTime() {
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.of(2008, 12, 18, 10, 20, 0, 0, ZoneId.of("GMT"));
|
||||
headers.setExpires(zonedDateTime);
|
||||
assertEquals("Invalid Expires header", zonedDateTime.toInstant().toEpochMilli(), headers.getExpires());
|
||||
assertEquals("Invalid Expires header", "Thu, 18 Dec 2008 10:20:00 GMT", headers.getFirst("expires"));
|
||||
}
|
||||
|
||||
@Test(expected = DateTimeException.class) // SPR-16560
|
||||
public void expiresLargeDate() {
|
||||
headers.setExpires(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test // SPR-10648 (example is from INT-3063)
|
||||
public void expiresInvalidDate() {
|
||||
headers.set("Expires", "-1");
|
||||
|
@ -332,9 +342,15 @@ public class HttpHeadersTests {
|
|||
|
||||
@Test
|
||||
public void cacheControl() {
|
||||
String cacheControl = "no-cache";
|
||||
headers.setCacheControl(cacheControl);
|
||||
assertEquals("Invalid Cache-Control header", cacheControl, headers.getCacheControl());
|
||||
headers.setCacheControl("no-cache");
|
||||
assertEquals("Invalid Cache-Control header", "no-cache", headers.getCacheControl());
|
||||
assertEquals("Invalid Cache-Control header", "no-cache", headers.getFirst("cache-control"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheControlBuilder() {
|
||||
headers.setCacheControl(CacheControl.noCache());
|
||||
assertEquals("Invalid Cache-Control header", "no-cache", headers.getCacheControl());
|
||||
assertEquals("Invalid Cache-Control header", "no-cache", headers.getFirst("cache-control"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue