diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index cf5c5fce246..ce031bd5ff8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -743,11 +743,13 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter mav = invokeHandlerMethod(request, response, handlerMethod); } - if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { - applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); - } - else { - prepareResponse(response); + if (!response.containsHeader(HEADER_CACHE_CONTROL)) { + if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { + applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); + } + else { + prepareResponse(response); + } } return mav; @@ -887,7 +889,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter } List initBinderMethods = new ArrayList(); // Global methods first - for (Entry> entry : this.initBinderAdviceCache .entrySet()) { + for (Entry> entry : this.initBinderAdviceCache.entrySet()) { if (entry.getKey().isApplicableToBeanType(handlerType)) { Object bean = entry.getKey().resolveBean(); for (Method method : entry.getValue()) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java index 8bf68bba4a8..903aaa4c7e6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java @@ -71,7 +71,7 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport { private static final String HEADER_EXPIRES = "Expires"; - private static final String HEADER_CACHE_CONTROL = "Cache-Control"; + protected static final String HEADER_CACHE_CONTROL = "Cache-Control"; /** Set of supported HTTP methods */ @@ -330,16 +330,14 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport { * @since 4.2 */ protected final void applyCacheControl(HttpServletResponse response, CacheControl cacheControl) { - if (!response.containsHeader(HEADER_CACHE_CONTROL)) { - String ccValue = cacheControl.getHeaderValue(); - 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, ""); - } + String ccValue = cacheControl.getHeaderValue(); + 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, ""); } } } @@ -355,32 +353,30 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport { */ @SuppressWarnings("deprecation") protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds) { - if (!response.containsHeader(HEADER_CACHE_CONTROL)) { - 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); + 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); + } + } + 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 { - 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); } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index bfbda11fc90..453bdbdcb17 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -503,6 +503,17 @@ public class ResourceHttpRequestHandlerTests { assertEquals(0, this.response.getContentLength()); } + // SPR-14005 + @Test + public void doOverwriteExistingCacheControlHeaders() throws Exception { + this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css"); + this.response.setHeader("Cache-Control", "no-store"); + + this.handler.handleRequest(this.request, this.response); + + assertEquals("max-age=3600", this.response.getHeader("Cache-Control")); + } + private long dateHeaderAsLong(String responseHeaderName) throws Exception { return dateFormat.parse(this.response.getHeader(responseHeaderName)).getTime();