Remove deprecated API in WebContentGenerator

Closes gh-31492
This commit is contained in:
Brian Clozel 2024-03-11 15:35:12 +01:00 committed by Brian Clozel
parent 92d1ebefbb
commit 9af4f5cf17
2 changed files with 8 additions and 297 deletions

View File

@ -50,13 +50,6 @@ import org.springframework.web.context.support.WebApplicationObjectSupport;
* headers can be controlled via the {@link #setCacheSeconds "cacheSeconds"}
* and {@link #setCacheControl "cacheControl"} properties.
*
* <p><b>NOTE:</b> As of Spring 4.2, this generator's default behavior changed when
* using only {@link #setCacheSeconds}, sending HTTP response headers that are in line
* with current browsers and proxies implementations (i.e. no HTTP 1.0 headers anymore)
* Reverting to the previous behavior can be easily done by using one of the newly
* deprecated methods {@link #setUseExpiresHeader}, {@link #setUseCacheControlHeader},
* {@link #setUseCacheControlNoStore} or {@link #setAlwaysMustRevalidate}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Brian Clozel
@ -76,10 +69,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
/** HTTP method "POST". */
public static final String METHOD_POST = "POST";
private static final String HEADER_PRAGMA = "Pragma";
private static final String HEADER_EXPIRES = "Expires";
protected static final String HEADER_CACHE_CONTROL = "Cache-Control";
@ -101,20 +90,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
private String[] varyByRequestHeaders;
// deprecated fields
/** Use HTTP 1.0 expires header? */
private boolean useExpiresHeader = false;
/** Use HTTP 1.1 cache-control header? */
private boolean useCacheControlHeader = true;
/** Use HTTP 1.1 cache-control header value "no-store"? */
private boolean useCacheControlNoStore = true;
private boolean alwaysMustRevalidate = false;
/**
* Create a new WebContentGenerator which supports
* HTTP methods GET, HEAD and POST by default.
@ -284,90 +259,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
return this.varyByRequestHeaders;
}
/**
* Set whether to use the HTTP 1.0 expires header. Default is "false",
* as of 4.2.
* <p>Note: Cache headers will only get applied if caching is enabled
* (or explicitly prevented) for the current request.
* @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
* header will be required, with the HTTP 1.0 headers disappearing
*/
@Deprecated
public final void setUseExpiresHeader(boolean useExpiresHeader) {
this.useExpiresHeader = useExpiresHeader;
}
/**
* Return whether the HTTP 1.0 expires header is used.
* @deprecated as of 4.2, in favor of {@link #getCacheControl()}
*/
@Deprecated
public final boolean isUseExpiresHeader() {
return this.useExpiresHeader;
}
/**
* Set whether to use the HTTP 1.1 cache-control header. Default is "true".
* <p>Note: Cache headers will only get applied if caching is enabled
* (or explicitly prevented) for the current request.
* @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
* header will be required, with the HTTP 1.0 headers disappearing
*/
@Deprecated
public final void setUseCacheControlHeader(boolean useCacheControlHeader) {
this.useCacheControlHeader = useCacheControlHeader;
}
/**
* Return whether the HTTP 1.1 cache-control header is used.
* @deprecated as of 4.2, in favor of {@link #getCacheControl()}
*/
@Deprecated
public final boolean isUseCacheControlHeader() {
return this.useCacheControlHeader;
}
/**
* Set whether to use the HTTP 1.1 cache-control header value "no-store"
* when preventing caching. Default is "true".
* @deprecated as of 4.2, in favor of {@link #setCacheControl}
*/
@Deprecated
public final void setUseCacheControlNoStore(boolean useCacheControlNoStore) {
this.useCacheControlNoStore = useCacheControlNoStore;
}
/**
* Return whether the HTTP 1.1 cache-control header value "no-store" is used.
* @deprecated as of 4.2, in favor of {@link #getCacheControl()}
*/
@Deprecated
public final boolean isUseCacheControlNoStore() {
return this.useCacheControlNoStore;
}
/**
* An option to add 'must-revalidate' to every Cache-Control header.
* This may be useful with annotated controller methods, which can
* programmatically do a last-modified calculation as described in
* {@link org.springframework.web.context.request.WebRequest#checkNotModified(long)}.
* <p>Default is "false".
* @deprecated as of 4.2, in favor of {@link #setCacheControl}
*/
@Deprecated
public final void setAlwaysMustRevalidate(boolean mustRevalidate) {
this.alwaysMustRevalidate = mustRevalidate;
}
/**
* Return whether 'must-revalidate' is added to every Cache-Control header.
* @deprecated as of 4.2, in favor of {@link #getCacheControl()}
*/
@Deprecated
public final boolean isAlwaysMustRevalidate() {
return this.alwaysMustRevalidate;
}
/**
* Check the given request for supported methods and a required session, if any.
@ -425,15 +316,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
if (ccValue != null) {
// Set computed HTTP 1.1 Cache-Control header
response.setHeader(HEADER_CACHE_CONTROL, ccValue);
if (response.containsHeader(HEADER_PRAGMA)) {
// Reset HTTP 1.0 Pragma header if present
response.setHeader(HEADER_PRAGMA, "");
}
if (response.containsHeader(HEADER_EXPIRES)) {
// Reset HTTP 1.0 Expires header if present
response.setHeader(HEADER_EXPIRES, "");
}
}
}
@ -446,33 +328,18 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
* @param cacheSeconds positive number of seconds into the future that the
* response should be cacheable for, 0 to prevent caching
*/
@SuppressWarnings("deprecation")
protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds) {
if (this.useExpiresHeader || !this.useCacheControlHeader) {
// Deprecated HTTP 1.0 cache behavior, as in previous Spring versions
if (cacheSeconds > 0) {
cacheForSeconds(response, cacheSeconds);
}
else if (cacheSeconds == 0) {
preventCaching(response);
}
CacheControl cControl;
if (cacheSeconds > 0) {
cControl = CacheControl.maxAge(cacheSeconds, TimeUnit.SECONDS);
}
else if (cacheSeconds == 0) {
cControl = CacheControl.noStore();
}
else {
CacheControl cControl;
if (cacheSeconds > 0) {
cControl = CacheControl.maxAge(cacheSeconds, TimeUnit.SECONDS);
if (this.alwaysMustRevalidate) {
cControl = cControl.mustRevalidate();
}
}
else if (cacheSeconds == 0) {
cControl = (this.useCacheControlNoStore ? CacheControl.noStore() : CacheControl.noCache());
}
else {
cControl = CacheControl.empty();
}
applyCacheControl(response, cControl);
cControl = CacheControl.empty();
}
applyCacheControl(response, cControl);
}
@ -493,105 +360,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
applyCacheSeconds(response, cacheSeconds);
}
/**
* Apply the given cache seconds and generate respective HTTP headers.
* <p>That is, allow caching for the given number of seconds in the
* case of a positive value, prevent caching if given a 0 value, else
* do nothing (i.e. leave caching to the client).
* @param response the current HTTP response
* @param cacheSeconds the (positive) number of seconds into the future
* that the response should be cacheable for; 0 to prevent caching; and
* a negative value to leave caching to the client.
* @param mustRevalidate whether the client should revalidate the resource
* (typically only necessary for controllers with last-modified support)
* @deprecated as of 4.2, in favor of {@link #applyCacheControl}
*/
@Deprecated
protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds, boolean mustRevalidate) {
if (cacheSeconds > 0) {
cacheForSeconds(response, cacheSeconds, mustRevalidate);
}
else if (cacheSeconds == 0) {
preventCaching(response);
}
}
/**
* Set HTTP headers to allow caching for the given number of seconds.
* Does not tell the browser to revalidate the resource.
* @param response current HTTP response
* @param seconds number of seconds into the future that the response
* should be cacheable for
* @deprecated as of 4.2, in favor of {@link #applyCacheControl}
*/
@Deprecated
protected final void cacheForSeconds(HttpServletResponse response, int seconds) {
cacheForSeconds(response, seconds, false);
}
/**
* Set HTTP headers to allow caching for the given number of seconds.
* Tells the browser to revalidate the resource if mustRevalidate is
* {@code true}.
* @param response the current HTTP response
* @param seconds number of seconds into the future that the response
* should be cacheable for
* @param mustRevalidate whether the client should revalidate the resource
* (typically only necessary for controllers with last-modified support)
* @deprecated as of 4.2, in favor of {@link #applyCacheControl}
*/
@Deprecated
protected final void cacheForSeconds(HttpServletResponse response, int seconds, boolean mustRevalidate) {
if (this.useExpiresHeader) {
// HTTP 1.0 header
response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + seconds * 1000L);
}
else if (response.containsHeader(HEADER_EXPIRES)) {
// Reset HTTP 1.0 Expires header if present
response.setHeader(HEADER_EXPIRES, "");
}
if (this.useCacheControlHeader) {
// HTTP 1.1 header
String headerValue = "max-age=" + seconds;
if (mustRevalidate || this.alwaysMustRevalidate) {
headerValue += ", must-revalidate";
}
response.setHeader(HEADER_CACHE_CONTROL, headerValue);
}
if (response.containsHeader(HEADER_PRAGMA)) {
// Reset HTTP 1.0 Pragma header if present
response.setHeader(HEADER_PRAGMA, "");
}
}
/**
* Prevent the response from being cached.
* Only called in HTTP 1.0 compatibility mode.
* <p>See {@code https://www.mnot.net/cache_docs}.
* @deprecated as of 4.2, in favor of {@link #applyCacheControl}
*/
@Deprecated
protected final void preventCaching(HttpServletResponse response) {
response.setHeader(HEADER_PRAGMA, "no-cache");
if (this.useExpiresHeader) {
// HTTP 1.0 Expires header
response.setDateHeader(HEADER_EXPIRES, 1L);
}
if (this.useCacheControlHeader) {
// HTTP 1.1 Cache-Control header: "no-cache" is the standard value,
// "no-store" is necessary to prevent caching on Firefox.
response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
if (this.useCacheControlNoStore) {
response.addHeader(HEADER_CACHE_CONTROL, "no-store");
}
}
}
private Collection<String> getVaryRequestHeadersToAdd(HttpServletResponse response, String[] varyByRequestHeaders) {
if (!response.containsHeader(HttpHeaders.VARY)) {
return Arrays.asList(varyByRequestHeaders);

View File

@ -103,63 +103,6 @@ class WebContentInterceptorTests {
assertThat(cacheControlHeaders).isEmpty();
}
@PathPatternsParameterizedTest // SPR-13252, SPR-14053
void cachingConfigAndPragmaHeader(Function<String, MockHttpServletRequest> requestFactory) throws Exception {
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
interceptor.setCacheSeconds(10);
interceptor.preHandle(requestFactory.apply("/"), response, handler);
assertThat(response.getHeader("Pragma")).isEmpty();
assertThat(response.getHeader("Expires")).isEmpty();
}
@SuppressWarnings("deprecation")
@PathPatternsParameterizedTest // SPR-13252, SPR-14053
void http10CachingConfigAndPragmaHeader(Function<String, MockHttpServletRequest> requestFactory) throws Exception {
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
interceptor.setCacheSeconds(10);
interceptor.setAlwaysMustRevalidate(true);
interceptor.preHandle(requestFactory.apply("/"), response, handler);
assertThat(response.getHeader("Pragma")).isEmpty();
assertThat(response.getHeader("Expires")).isEmpty();
}
@SuppressWarnings("deprecation")
@PathPatternsParameterizedTest
void http10CachingConfigAndSpecificMapping(Function<String, MockHttpServletRequest> requestFactory) throws Exception {
interceptor.setCacheSeconds(0);
interceptor.setUseExpiresHeader(true);
interceptor.setAlwaysMustRevalidate(true);
Properties mappings = new Properties();
mappings.setProperty("/*/*.cache.html", "10");
interceptor.setCacheMappings(mappings);
MockHttpServletRequest request = requestFactory.apply("/foo/page.html");
MockHttpServletResponse response = new MockHttpServletResponse();
interceptor.preHandle(request, response, handler);
Iterable<String> expiresHeaders = response.getHeaders("Expires");
assertThat(expiresHeaders).hasSize(1);
Iterable<String> cacheControlHeaders = response.getHeaders("Cache-Control");
assertThat(cacheControlHeaders).containsExactly("no-cache", "no-store");
Iterable<String> pragmaHeaders = response.getHeaders("Pragma");
assertThat(pragmaHeaders).containsExactly("no-cache");
request = requestFactory.apply("/foo/page.cache.html");
response = new MockHttpServletResponse();
interceptor.preHandle(request, response, handler);
expiresHeaders = response.getHeaders("Expires");
assertThat(expiresHeaders).hasSize(1);
cacheControlHeaders = response.getHeaders("Cache-Control");
assertThat(cacheControlHeaders).containsExactly("max-age=10, must-revalidate");
}
@Test
void throwsExceptionWithNullPathMatcher() {
assertThatIllegalArgumentException()