2
* Copyright (c) 2002-2003 by OpenSymphony
5
package com.opensymphony.oscache.web.filter;
7
import com.opensymphony.oscache.base.Cache;
8
import com.opensymphony.oscache.base.NeedsRefreshException;
9
import com.opensymphony.oscache.web.ServletCacheAdministrator;
11
import org.apache.commons.logging.Log;
12
import org.apache.commons.logging.LogFactory;
14
import java.io.IOException;
16
import javax.servlet.*;
17
import javax.servlet.http.HttpServletRequest;
18
import javax.servlet.http.HttpServletResponse;
19
import javax.servlet.jsp.PageContext;
22
* CacheFilter is a filter that allows for server-side caching of post-processed servlet content.<p>
24
* It also gives great programatic control over refreshing, flushing and updating the cache.<p>
26
* @author <a href="mailto:sergek@lokitech.com">Serge Knystautas</a>
27
* @author <a href="mailto:mike@atlassian.com">Mike Cannon-Brookes</a>
28
* @version $Revision: 1.2 $
30
public class CacheFilter implements Filter {
31
private final Log log = LogFactory.getLog(this.getClass());
34
private FilterConfig config;
35
private ServletCacheAdministrator admin = null;
36
private int cacheScope = PageContext.APPLICATION_SCOPE; // filter scope - default is APPLICATION
37
private int time = 60 * 60; // time before cache should be refreshed - default one hour (in seconds)
42
public void destroy() {
47
* The doFilter call caches the response by wrapping the <code>HttpServletResponse</code>
48
* object so that the output stream can be caught. This works by splitting off the output
49
* stream into two with the {@link SplitServletOutputStream} class. One stream gets written
50
* out to the response as normal, the other is fed into a byte array inside a {@link ResponseContent}
53
* @param request The servlet request
54
* @param response The servlet response
55
* @param chain The filter chain
56
* @throws ServletException IOException
58
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
59
log.info("<cache>: filter in scope " + cacheScope);
61
HttpServletRequest httpRequest = (HttpServletRequest) request;
62
String key = admin.generateEntryKey(null, httpRequest, cacheScope);
63
Cache cache = admin.getCache(httpRequest, cacheScope);
66
ResponseContent respContent = (ResponseContent) cache.getFromCache(key, time);
67
log.info("<cache>: Using cached entry for " + key);
68
respContent.writeTo(response);
69
} catch (NeedsRefreshException nre) {
70
boolean updateSucceeded = false;
73
log.info("<cache>: New cache entry, cache stale or cache scope flushed for " + key);
75
CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper((HttpServletResponse) response);
76
chain.doFilter(request, cacheResponse);
77
cacheResponse.flushBuffer();
79
// Only cache if the response was 200
80
if (cacheResponse.getStatus() == HttpServletResponse.SC_OK) {
81
//Store as the cache content the result of the response
82
cache.putInCache(key, cacheResponse.getContent());
83
updateSucceeded = true;
86
if (!updateSucceeded) {
87
cache.cancelUpdate(key);
94
* Initialize the filter. This retrieves a {@link ServletCacheAdministrator}
95
* instance and configures the filter based on any initialization parameters.<p>
96
* The supported initialization parameters are:
98
* <li><b>time</b> - the default time (in seconds) to cache content for. The default
99
* value is 3600 seconds (one hour).</li>
100
* <li><b>scope</b> - the default scope to cache content in. Acceptable values
101
* are <code>application</code> (default), <code>session</code>, <code>request</code> and
104
* @param filterConfig The filter configuration
106
public void init(FilterConfig filterConfig) {
107
//Get whatever settings we want...
108
config = filterConfig;
109
admin = ServletCacheAdministrator.getInstance(config.getServletContext());
111
//Will work this out later
113
time = Integer.parseInt(config.getInitParameter("time"));
114
} catch (Exception e) {
115
log.info("Could not get init paramter 'time', defaulting to one hour.");
119
String scopeString = config.getInitParameter("scope");
121
if (scopeString.equals("session")) {
122
cacheScope = PageContext.SESSION_SCOPE;
123
} else if (scopeString.equals("application")) {
124
cacheScope = PageContext.APPLICATION_SCOPE;
125
} else if (scopeString.equals("request")) {
126
cacheScope = PageContext.REQUEST_SCOPE;
127
} else if (scopeString.equals("page")) {
128
cacheScope = PageContext.PAGE_SCOPE;
130
} catch (Exception e) {
131
log.info("Could not get init paramter 'scope', defaulting to 'application'");