diff --git a/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControl.java b/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControl.java
index b0a91c6..ec34ea1 100644
--- a/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControl.java
+++ b/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControl.java
@@ -36,4 +36,9 @@
*/
int sharedMaxAge() default -1;
+ /**
+ * Sometimes caching need vary headers. E.g. 'Accept'.
+ */
+ String[] vary() default {};
+
}
diff --git a/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptor.java b/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptor.java
index 5b8be21..1aee7a4 100644
--- a/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptor.java
+++ b/spring-mvc-cache-control/src/main/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptor.java
@@ -14,7 +14,7 @@
/**
* Provides a cache control handler interceptor to assign cache-control
* headers to HTTP responses.
- *
+ *
* @author Scott Rossillo
*
*/
@@ -22,46 +22,51 @@ public class CacheControlHandlerInterceptor extends HandlerInterceptorAdapter im
private static final String HEADER_EXPIRES = "Expires";
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
-
+ private static final String HEADER_VARY = "Vary";
+
private boolean useExpiresHeader = true;
-
+
/**
* Creates a new cache control handler interceptor.
*/
public CacheControlHandlerInterceptor() {
super();
}
-
+
/**
* Assigns a CacheControl
header to the given response
.
- *
+ *
* @param request the HttpServletRequest
* @param response the HttpServletResponse
* @param handler the handler for the given request
*/
protected final void assignCacheControlHeader(
final HttpServletRequest request,
- final HttpServletResponse response,
+ final HttpServletResponse response,
final Object handler) {
-
+
final CacheControl cacheControl = this.getCacheControl(request, response, handler);
final String cacheControlHeader = this.createCacheControlHeader(cacheControl);
-
+
if (cacheControlHeader != null) {
response.setHeader(HEADER_CACHE_CONTROL, cacheControlHeader);
if (useExpiresHeader) {
response.setDateHeader(HEADER_EXPIRES, createExpiresHeader(cacheControl));
}
+ String[] vary = cacheControl.vary();
+ for (String v : vary) {
+ response.addHeader(HEADER_VARY, v);
+ }
}
}
-
+
/**
* Returns cache control header value from the given {@link CacheControl}
* annotation.
- *
+ *
* @param cacheControl the CacheControl
annotation from which to
* create the returned cache control header value
- *
+ *
* @return the cache control header value
*/
protected final String createCacheControlHeader(final CacheControl cacheControl) {
@@ -96,77 +101,77 @@ protected final String createCacheControlHeader(final CacheControl cacheControl)
return (builder.length() > 0 ? builder.toString() : null);
}
-
+
/**
- * Returns an expires header value generated from the given
+ * Returns an expires header value generated from the given
* {@link CacheControl} annotation.
- *
+ *
* @param cacheControl the CacheControl
annotation from which to
* create the returned expires header value
- *
+ *
* @return the expires header value
*/
protected final long createExpiresHeader(final CacheControl cacheControl) {
-
+
final Calendar expires = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
-
+
if (cacheControl.maxAge() >= 0) {
expires.add(Calendar.SECOND, cacheControl.maxAge());
}
-
+
return expires.getTime().getTime();
}
-
+
/**
* Returns the {@link CacheControl} annotation specified for the
* given request, response and handler.
- *
+ *
* @param request the current HttpServletRequest
* @param response the current HttpServletResponse
* @param handler the current request handler
- *
+ *
* @return the CacheControl
annotation specified by
* the given handler
if present; null
otherwise
*/
protected final CacheControl getCacheControl(
final HttpServletRequest request,
- final HttpServletResponse response,
+ final HttpServletResponse response,
final Object handler) {
-
+
if (handler == null || !(handler instanceof HandlerMethod)) {
return null;
}
-
+
final HandlerMethod handlerMethod = (HandlerMethod) handler;
CacheControl cacheControl = handlerMethod.getMethodAnnotation(CacheControl.class);
-
+
if (cacheControl == null) {
return handlerMethod.getBeanType().getAnnotation(CacheControl.class);
}
-
+
return cacheControl;
}
-
+
@Override
public final boolean preHandle(
final HttpServletRequest request,
- final HttpServletResponse response,
+ final HttpServletResponse response,
final Object handler) throws Exception {
-
+
this.assignCacheControlHeader(request, response, handler);
-
+
return super.preHandle(request, response, handler);
}
/**
* True to set an expires header when a {@link CacheControl} annotation is present
* on a handler; false otherwise. Defaults to true.
- *
- * @param useExpiresHeader true
to set an expires header when a
+ *
+ * @param useExpiresHeader true
to set an expires header when a
* CacheControl
annotation is present on a handler; false
otherwise
*/
public final void setUseExpiresHeader(final boolean useExpiresHeader) {
this.useExpiresHeader = useExpiresHeader;
}
-
+
}
diff --git a/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlAnnotatedTestController.java b/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlAnnotatedTestController.java
index c129961..c3a54b7 100644
--- a/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlAnnotatedTestController.java
+++ b/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlAnnotatedTestController.java
@@ -25,6 +25,11 @@ public String handlePubliclyCachedPageAndProxyRevalidatedRequest() {
public String handlePrivatelyCachedPageRequest() {
return null;
}
+
+ @CacheControl(policy = CachePolicy.PRIVATE, maxAge = 360, vary = "Accept")
+ public String handlePrivatelyCachedPageRequestWithVary() {
+ return null;
+ }
public String handleWithDefaultPolicy() {
return null;
diff --git a/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptorTest.java b/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptorTest.java
index 0d86863..c9d3e88 100644
--- a/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptorTest.java
+++ b/spring-mvc-cache-control/src/test/java/net/rossillo/spring/web/mvc/CacheControlHandlerInterceptorTest.java
@@ -97,7 +97,25 @@ public void testCacheControlPrivate() throws Exception {
assertTrue(response.getHeader("Cache-Control").contains("private"));
assertFalse(response.getHeader("Cache-Control").contains("public"));
}
-
+
+ @Test
+ public void testCacheControlPrivateWithVary() throws Exception {
+
+ final HandlerMethod handler = new HandlerMethod(
+ controller,
+ controller.getClass().getMethod("handlePrivatelyCachedPageRequestWithVary"));
+
+ interceptor.preHandle(request, response, handler);
+
+ System.err.println("Vary: " + response.getHeader("Vary"));
+
+ assertNotNull(response.getHeader("Cache-Control"));
+ assertTrue(response.getHeader("Cache-Control").contains("private"));
+ assertFalse(response.getHeader("Cache-Control").contains("public"));
+ assertTrue(response.getHeader("Vary").contains("Accept"));
+
+ }
+
@Test
public void testExpires() throws Exception {