Class CacheControlFilter
- java.lang.Object
-
- org.omnifaces.filter.HttpFilter
-
- org.omnifaces.filter.CacheControlFilter
-
- All Implemented Interfaces:
Filter
public class CacheControlFilter extends HttpFilter
This filter will control the cache-related headers of the response. Cache-related headers have a major impact on performance (network bandwidth and server load) and user experience (up to date content and non-expired views).
By default, when no initialization parameters are specified, the filter will instruct the client (generally, the webbrowser) to not cache the response. This is recommended on dynamic pages with stateful forms with a
jakarta.faces.ViewStatehidden field. If such a page were cached, and the enduser navigates to it by webbrowser's back button, and then re-submits it, then the enduser would face aViewExpiredException.However, on stateless resources, caching the response would be beneficial. Set the expire time to the same time as you'd like to use as refresh interval of the resource, which can be 10 seconds (to avoid F5-madness on resources which are subject to quick changes), but also minutes or even hours, days or weeks. For example, a list of links, a news page, a JS/CSS/image file, etc.
Any sane server and client adheres the following rules as to caching:
- When the enduser performs page-to-page navigation, or when the enduser selects URL in address bar and presses enter key again, while the resource is cached, then the client will just load it from the cache without hitting the server in any way.
- Or when the cache is expired, or when the enduser does a soft-refresh by pressing refresh button or F5 key, then:
- When the
ETagorLast-Modifiedheader is present on cached resource, then the client will perform a so-called conditional GET request withIf-None-MatchorIf-Modified-Sinceheaders. If the server responds with HTTP status 304 ("not modified") along with the updated cache-related headers, then the client will keep the resource in cache and expand its expire time based on the headers. Note:ETagtakes precedence overLast-Modifiedwhen both are present and consequentlyIf-None-Matchtakes precedence overIf-Modified-Sincewhen both are present. - When those headers are not present, then the behavior is the same as during a hard-refresh.
- When the
- Or when the resource is not cached, or when the enduser does a hard-refresh by pressing
Ctrlkey along with refresh button or F5, then the webbrowser will perform a fresh new request and purge any cached resource.
Important notice: this filter automatically skips Faces resources, such as the ones served by
<h:outputScript>,<h:outputStylesheet>,@ResourceDependency, etc. Their cache-related headers are namely already controlled by theResourceHandlerimplementation. In Mojarra and MyFaces, the default expiration time is 1 week (604800000 milliseconds), which can be configured by aweb.xmlcontext parameter with the following name and a value in milliseconds, e.g.3628800000for 6 weeks:- Mojarra:
com.sun.faces.defaultResourceMaxAge - MyFaces:
org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES
It would not make sense to control their cache-related headers with this filter as they would be overridden anyway.
Configuration
This filter supports the
expiresinitialization parameter which must be a number between 0 and 999999999 with optionally the 'w', 'd', 'h', 'm' or 's' suffix standing for respectively 'week', 'day', 'hour', 'minute' and 'second'. For example: '6w' is 6 weeks. The default suffix is 's'. So, when the suffix is omitted, it's treated as seconds. For example: '86400' is 86400 seconds, which is effectively equal to '86400s', '1440m', '24h' and '1d'.Imagine that you've the following resources:
- All
/forum/*pages: cache 10 seconds. - All
*.pdfand*.zipfiles: cache 2 days. - All other pages: no cache.
Then you can configure the filter as follows (filter name is fully free to your choice, but keep it sensible):
<filter> <filter-name>noCache</filter-name> <filter-class>org.omnifaces.filter.CacheControlFilter</filter-class> </filter> <filter> <filter-name>cache10seconds</filter-name> <filter-class>org.omnifaces.filter.CacheControlFilter</filter-class> <init-param> <param-name>expires</param-name> <param-value>10s</param-value> </init-param> </filter> <filter> <filter-name>cache2days</filter-name> <filter-class>org.omnifaces.filter.CacheControlFilter</filter-class> <init-param> <param-name>expires</param-name> <param-value>2d</param-value> </init-param> </filter> <filter-mapping> <filter-name>noCache</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>cache10seconds</filter-name> <url-pattern>/forum/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>cache2days</filter-name> <url-pattern>*.pdf</url-pattern> <url-pattern>*.zip</url-pattern> </filter-mapping>Note: put the more specific URL patterns in the end of filter mappings. Due to the way how filters work, there's unfortunately no simple way to skip the filter on
/*when e.g.*.pdfis matched. You can always map the no cache filter specifically toFacesServletif you intend to disable caching on all Faces pages. Here's an example assuming that you've configured theFacesServletwith a servlet name offacesServlet:<filter-mapping> <filter-name>noCache</filter-name> <servlet-name>facesServlet</servlet-name> </filter-mapping>Actual headers
If the
expiresinit param is set with a value which represents a time larger than 0 seconds, then the following headers will be set:Cache-Control: public,max-age=[expiration time in seconds],must-revalidateExpires: [expiration date of now plus expiration time in seconds]
If the
expiresinit param is absent, or set with a value which represents a time equal to 0 seconds, then the following headers will be set:Cache-Control: no-cache,no-store,must-revalidateExpires: [expiration date of 0]Pragma: no-cache
Faces development stage
To speed up development, caching by this filter is disabled when Faces project stage is set to
Developmentas perServlets.isFacesDevelopment(jakarta.servlet.ServletContext).- Since:
- 1.7
- Author:
- Bauke Scholtz
- See Also:
HttpFilter
-
-
Constructor Summary
Constructors Constructor Description CacheControlFilter()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voiddoFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain)Set the necessary response headers based onexpiresinitialization parameter.voidinit()Initialize theexpiresparameter.-
Methods inherited from class org.omnifaces.filter.HttpFilter
destroy, doFilter, getFilterConfig, getInitParameter, getServletContext, init
-
-
-
-
Method Detail
-
init
public void init() throws ServletExceptionInitialize theexpiresparameter.- Overrides:
initin classHttpFilter- Throws:
ServletException- When filter's initialization failed.
-
doFilter
public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain) throws ServletException, IOException
Set the necessary response headers based onexpiresinitialization parameter.- Specified by:
doFilterin classHttpFilter- Parameters:
request- The HTTP request.response- The HTTP response.session- The HTTP session, if any, elsenull.chain- The filter chain to continue.- Throws:
ServletException- As wrapper exception when something fails in the request processing.IOException- Whenever something fails at I/O level.- See Also:
Filter.doFilter(ServletRequest, ServletResponse, FilterChain)
-
-