diff --git a/src/main/java/com/samaxes/filter/NoCacheFilter.java b/src/main/java/com/samaxes/filter/NoCacheFilter.java index 625c6fd..75c860c 100644 --- a/src/main/java/com/samaxes/filter/NoCacheFilter.java +++ b/src/main/java/com/samaxes/filter/NoCacheFilter.java @@ -19,6 +19,8 @@ package com.samaxes.filter; import java.io.IOException; +import java.util.LinkedList; +import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -28,12 +30,40 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; +import com.samaxes.filter.util.Cacheability; import com.samaxes.filter.util.HTTPCacheHeader; +import com.samaxes.filter.util.StringUtil; /** *

* Filter allowing to completely disable browser caching. *

+ *

Options

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
OptionRequiredDefaultSinceDescription
{@code no-cache}No{@code true}2.4Forces caches to submit the request to the origin server for validation before releasing a cached copy. + *
{@code no-store}No{@code true}2.4The cache should not store anything about the client request or server response. + *
*

Sample configuration:

*

* Declare the filter in your web descriptor file {@code web.xml}: @@ -71,11 +101,25 @@ */ public class NoCacheFilter implements Filter { + private static Cacheability[] ALLOWED_DIRECTIVES = new Cacheability[]{Cacheability.NO_CACHE, Cacheability.NO_STORE}; + + private String cacheControl; + /** * {@inheritDoc} */ @Override public void init(FilterConfig filterConfig) throws ServletException { + List cacheControlDirectives = new LinkedList(); + + for (Cacheability allowedDirective : ALLOWED_DIRECTIVES) { + String directive = allowedDirective.getValue(); + String filterConfigValue = filterConfig.getInitParameter(directive); + if (filterConfigValue == null || Boolean.valueOf(filterConfigValue)) { + cacheControlDirectives.add(directive); + } + } + cacheControl = StringUtil.join(", ", cacheControlDirectives.toArray(new String[]{})); } /** @@ -90,7 +134,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; // set cache directives - httpServletResponse.setHeader(HTTPCacheHeader.CACHE_CONTROL.getName(), "no-cache, no-store"); + httpServletResponse.setHeader(HTTPCacheHeader.CACHE_CONTROL.getName(), cacheControl); httpServletResponse.setDateHeader(HTTPCacheHeader.EXPIRES.getName(), 0L); filterChain.doFilter(servletRequest, servletResponse); diff --git a/src/main/java/com/samaxes/filter/util/Cacheability.java b/src/main/java/com/samaxes/filter/util/Cacheability.java index 680a1f3..619ad26 100644 --- a/src/main/java/com/samaxes/filter/util/Cacheability.java +++ b/src/main/java/com/samaxes/filter/util/Cacheability.java @@ -26,11 +26,16 @@ * @version 2.3.1 */ public enum Cacheability { + NO_CACHE("no-cache"), + + NO_STORE("no-store"), + /** * Indicates that the response MAY be cached by any cache, even if it would normally be non-cacheable or cacheable * only within a non-shared cache. */ PUBLIC("public"), + /** * Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a * shared cache. This allows an origin server to state that the specified parts of the response are intended for diff --git a/src/main/java/com/samaxes/filter/util/StringUtil.java b/src/main/java/com/samaxes/filter/util/StringUtil.java new file mode 100644 index 0000000..5a47f2b --- /dev/null +++ b/src/main/java/com/samaxes/filter/util/StringUtil.java @@ -0,0 +1,23 @@ +package com.samaxes.filter.util; + +public class StringUtil +{ + /** + * In abscence of {@link String#join} in 1.6 + * @param delimiter the delimiter that separates each element + * @param elements the elements to join together. + * + * @return a new {@code String} that is composed of the {@code elements} + * separated by the {@code delimiter} + */ + public static String join(CharSequence delimiter, CharSequence... elements) { + boolean first = true; + StringBuilder str = new StringBuilder(); + for (CharSequence s : elements) { + if (!first) str.append(delimiter); + str.append(s); + first = false; + } + return str.toString(); + } +}