
net.rossillo.spring.web.mvc.CacheControlHandlerInterceptor Maven / Gradle / Ivy
The newest version!
package net.rossillo.spring.web.mvc;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
* Provides a cache control handler interceptor to assign cache-control
* headers to HTTP responses.
*
* @author Scott Rossillo
*
*/
public class CacheControlHandlerInterceptor extends HandlerInterceptorAdapter implements HandlerInterceptor {
private static final String HEADER_EXPIRES = "Expires";
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
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 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));
}
}
}
/**
* 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) {
final StringBuilder builder = new StringBuilder();
if (cacheControl == null) {
return null;
}
final CachePolicy[] policies = cacheControl.policy();
if (cacheControl.maxAge() >= 0) {
builder.append("max-age=").append(cacheControl.maxAge());
}
if (cacheControl.sharedMaxAge() >= 0) {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append("s-maxage=").append(cacheControl.sharedMaxAge());
}
if (policies != null) {
for (final CachePolicy policy : policies) {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(policy.policy());
}
}
return (builder.length() > 0 ? builder.toString() : null);
}
/**
* 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 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 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
* CacheControl
annotation is present on a handler; false
otherwise
*/
public final void setUseExpiresHeader(final boolean useExpiresHeader) {
this.useExpiresHeader = useExpiresHeader;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy