ehcache

net.sf.ehcache.constructs.web.filter
Class CachingFilter

java.lang.Object
  extended by net.sf.ehcache.constructs.web.filter.Filter
      extended by net.sf.ehcache.constructs.web.filter.CachingFilter
All Implemented Interfaces:
javax.servlet.Filter
Direct Known Subclasses:
PageFragmentCachingFilter, SimplePageCachingFilter

public abstract class CachingFilter
extends Filter

An abstract CachingFilter.

This class should be sub-classed for each page to be cached.

The filters must be declared in the web.xml deployment descriptor. Then a mapping from a web resource, such as a JSP, Servlet or static resouce needs to be defined. Finally, a succession of mappings can be used to create a filter chain. See SRV.6 of the Servlet 2.3 specification for more details.

Care should be taken not to define a filter chain such that the same CachingFilter class is reentered. The CachingFilter uses the BlockingCache. It blocks until the thread which did a get which results in a null does a put. If reentry happens a second get happens before the first put. The second get could wait indefinitely. This situation is monitored and if it happens, an IllegalStateException will be thrown.

Version:
$Id: CachingFilter.java 191 2006-09-03 22:41:48Z gregluck $
Author:
@author Greg Luck

Field Summary
protected  BlockingCache blockingCache
          The cache holding the web pages.
 
Fields inherited from class net.sf.ehcache.constructs.web.filter.Filter
exceptionsToLogDifferently, exceptionsToLogDifferentlyLevel, filterConfig, NO_FILTER, suppressStackTraces
 
Constructor Summary
CachingFilter()
           
 
Method Summary
protected  PageInfo buildPage(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, javax.servlet.FilterChain chain)
          Builds the PageInfo object by passing the request along the filter chain
protected  PageInfo buildPageInfo(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, javax.servlet.FilterChain chain)
          Build page info either using the cache or building the page directly.
protected abstract  java.lang.String calculateKey(javax.servlet.http.HttpServletRequest httpRequest)
          CachingFilter works off a key.
protected  void checkNoReentry(javax.servlet.http.HttpServletRequest httpRequest)
          Check that this caching filter is not being reentered by the same recursively.
protected  void doDestroy()
          Destroys the filter.
protected  void doFilter(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, javax.servlet.FilterChain chain)
          Performs the filtering for a request.
 void doInit()
          Initialises blockingCache to use.
protected abstract  CacheManager getCacheManager()
          Gets the CacheManager for this CachingFilter.
protected abstract  java.lang.String getCacheName()
          A meaningful name representative of the JSP page being cached.
protected  void setContentType(javax.servlet.http.HttpServletResponse response, PageInfo pageInfo)
          Set the content type
protected  void setCookies(PageInfo pageInfo, javax.servlet.http.HttpServletResponse response)
          Set the serializableCookies
protected  void setHeaders(PageInfo pageInfo, boolean requestAcceptsGzipEncoding, javax.servlet.http.HttpServletResponse response)
          Set the headers in the response object, excluding the Gzip header
protected  void setStatus(javax.servlet.http.HttpServletResponse response, PageInfo pageInfo)
          Status code
protected  void writeContent(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, PageInfo pageInfo)
          Writes the response content.
protected  void writeResponse(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, PageInfo pageInfo)
          Writes the response from a PageInfo object.
 
Methods inherited from class net.sf.ehcache.constructs.web.filter.Filter
acceptsEncoding, acceptsGzipEncoding, destroy, doFilter, filterNotDisabled, getFilterConfig, init, logRequestHeaders
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

blockingCache

protected BlockingCache blockingCache
The cache holding the web pages. Ensure that all threads for a given cache name are using the same instance of this.

Constructor Detail

CachingFilter

public CachingFilter()
Method Detail

doInit

public void doInit()
            throws CacheException
Initialises blockingCache to use. The BlockingCache created by this method does not have a lock timeout set.

A timeout can be appled using blockingCache.setTimeoutMillis(int timeout) and takes effect immediately for all new requests

Specified by:
doInit in class Filter
Throws:
CacheException - The most likely cause is that a cache has not been configured in ehcache's configuration file ehcache.xml for the filter name

doDestroy

protected void doDestroy()
Destroys the filter.

Specified by:
doDestroy in class Filter

doFilter

protected void doFilter(javax.servlet.http.HttpServletRequest request,
                        javax.servlet.http.HttpServletResponse response,
                        javax.servlet.FilterChain chain)
                 throws AlreadyGzippedException,
                        AlreadyCommittedException,
                        FilterNonReentrantException,
                        LockTimeoutException,
                        java.lang.Exception
Performs the filtering for a request.

Specified by:
doFilter in class Filter
Parameters:
request -
response -
chain -
Throws:
AlreadyGzippedException - if a double gzip is attempted
AlreadyCommittedException - if the response was committed on the way in or the on the way back
FilterNonReentrantException - if an attempt is made to reenter this filter in the same request.
LockTimeoutException - if this request is waiting on another that is populating the cache entry and timeouts while waiting. Only occurs if the BlockingCache has a timeout set.
java.lang.Exception - for all other exceptions. They will be caught and logged in Filter.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)

buildPageInfo

protected PageInfo buildPageInfo(javax.servlet.http.HttpServletRequest request,
                                 javax.servlet.http.HttpServletResponse response,
                                 javax.servlet.FilterChain chain)
                          throws java.lang.Exception
Build page info either using the cache or building the page directly.

Some requests are for page fragments which should never be gzipped, or for other pages which are not gzipped.

Throws:
java.lang.Exception

buildPage

protected PageInfo buildPage(javax.servlet.http.HttpServletRequest request,
                             javax.servlet.http.HttpServletResponse response,
                             javax.servlet.FilterChain chain)
                      throws AlreadyGzippedException,
                             java.lang.Exception
Builds the PageInfo object by passing the request along the filter chain

Parameters:
request -
response -
chain -
Returns:
a Serializable value object for the page or page fragment
Throws:
AlreadyGzippedException - if an attempt is made to double gzip the body
java.lang.Exception

writeResponse

protected void writeResponse(javax.servlet.http.HttpServletRequest request,
                             javax.servlet.http.HttpServletResponse response,
                             PageInfo pageInfo)
                      throws java.io.IOException,
                             java.util.zip.DataFormatException,
                             ResponseHeadersNotModifiableException
Writes the response from a PageInfo object.

Parameters:
request -
response -
pageInfo -
Throws:
java.io.IOException
java.util.zip.DataFormatException
ResponseHeadersNotModifiableException

setContentType

protected void setContentType(javax.servlet.http.HttpServletResponse response,
                              PageInfo pageInfo)
Set the content type

Parameters:
response -
pageInfo -

setCookies

protected void setCookies(PageInfo pageInfo,
                          javax.servlet.http.HttpServletResponse response)
Set the serializableCookies

Parameters:
pageInfo -
response -

setStatus

protected void setStatus(javax.servlet.http.HttpServletResponse response,
                         PageInfo pageInfo)
Status code

Parameters:
response -
pageInfo -

setHeaders

protected void setHeaders(PageInfo pageInfo,
                          boolean requestAcceptsGzipEncoding,
                          javax.servlet.http.HttpServletResponse response)
Set the headers in the response object, excluding the Gzip header

Parameters:
pageInfo -
requestAcceptsGzipEncoding -
response -

getCacheName

protected abstract java.lang.String getCacheName()
A meaningful name representative of the JSP page being cached.

Returns:
the name of the cache to use for this filter.

getCacheManager

protected abstract CacheManager getCacheManager()
Gets the CacheManager for this CachingFilter. It is therefore up to subclasses what CacheManager to use.

This method was introduced in ehcache 1.2.1. Older versions used a singleton CacheManager instance created with the default factory method.

Returns:
the CacheManager to be used
Since:
1.2.1

calculateKey

protected abstract java.lang.String calculateKey(javax.servlet.http.HttpServletRequest httpRequest)
CachingFilter works off a key.

The key should be unique. Factors to consider in generating a key are:

Parameters:
httpRequest -
Returns:
the key, generally the URL plus request parameters

writeContent

protected void writeContent(javax.servlet.http.HttpServletRequest request,
                            javax.servlet.http.HttpServletResponse response,
                            PageInfo pageInfo)
                     throws java.io.IOException,
                            ResponseHeadersNotModifiableException
Writes the response content. This will be gzipped or non gzipped depending on whether the User Agent accepts GZIP encoding.

If the body is written gzipped a gzip header is added.

Parameters:
response -
pageInfo -
Throws:
java.io.IOException
ResponseHeadersNotModifiableException

checkNoReentry

protected void checkNoReentry(javax.servlet.http.HttpServletRequest httpRequest)
                       throws FilterNonReentrantException
Check that this caching filter is not being reentered by the same recursively. Recursive calls will block indefinitely because the first request has not yet unblocked the cache.

This condition usually indicates an error in filter chaining or RequestDispatcher dispatching.

Parameters:
httpRequest -
Throws:
FilterNonReentrantException - if reentry is detected

ehcache