cachehttpservletresponsewrapper.java
来自「oscache-2.4.1-full」· Java 代码 · 共 412 行
JAVA
412 行
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.oscache.web.filter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* CacheServletResponse is a serialized representation of a response
*
* @author <a href="mailto:sergek@lokitech.com">Serge Knystautas</a>
* @version $Revision: 469 $
*/
public class CacheHttpServletResponseWrapper extends HttpServletResponseWrapper {
private final Log log = LogFactory.getLog(this.getClass());
/**
* We cache the printWriter so we can maintain a single instance
* of it no matter how many times it is requested.
*/
private PrintWriter cachedWriter = null;
private ResponseContent result = null;
private SplitServletOutputStream cacheOut = null;
private boolean fragment = false;
private int status = SC_OK;
private long expires = CacheFilter.EXPIRES_ON;
private long lastModified = CacheFilter.LAST_MODIFIED_INITIAL;
private long cacheControl = -60;
/**
* Constructor
*
* @param response The servlet response
*/
public CacheHttpServletResponseWrapper(HttpServletResponse response) {
this(response, false, Long.MAX_VALUE, CacheFilter.EXPIRES_ON, CacheFilter.LAST_MODIFIED_INITIAL, -60);
}
/**
* Constructor
*
* @param response The servlet response
* @param fragment true if the repsonse indicates that it is a fragement of a page
* @param time the refresh time in millis
* @param lastModified defines if last modified header will be send, @see CacheFilter
* @param expires defines if expires header will be send, @see CacheFilter
* @param cacheControl defines if cache control header will be send, @see CacheFilter
*/
public CacheHttpServletResponseWrapper(HttpServletResponse response, boolean fragment, long time, long lastModified, long expires, long cacheControl) {
super(response);
result = new ResponseContent();
this.fragment = fragment;
this.expires = expires;
this.lastModified = lastModified;
this.cacheControl = cacheControl;
// only set inital values for last modified and expires, when a complete page is cached
if (!fragment) {
// setting a default last modified value based on object creation and remove the millis
if (lastModified == CacheFilter.LAST_MODIFIED_INITIAL) {
long current = System.currentTimeMillis();
current = current - (current % 1000);
result.setLastModified(current);
super.setDateHeader(CacheFilter.HEADER_LAST_MODIFIED, result.getLastModified());
}
// setting the expires value
if (expires == CacheFilter.EXPIRES_TIME) {
result.setExpires(result.getLastModified() + time);
super.setDateHeader(CacheFilter.HEADER_EXPIRES, result.getExpires());
}
// setting the cache control with max-age
if (this.cacheControl == CacheFilter.MAX_AGE_TIME) {
// set the count down
long maxAge = System.currentTimeMillis();
maxAge = maxAge - (maxAge % 1000) + time;
result.setMaxAge(maxAge);
super.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + time / 1000);
} else if (this.cacheControl != CacheFilter.MAX_AGE_NO_INIT) {
result.setMaxAge(this.cacheControl);
super.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + (-this.cacheControl));
} else if (this.cacheControl == CacheFilter.MAX_AGE_NO_INIT ) {
result.setMaxAge(this.cacheControl);
}
}
}
/**
* Get a response content
*
* @return The content
*/
public ResponseContent getContent() {
// Flush the buffer
try {
flush();
} catch (IOException ignore) {
}
// Create the byte array
result.commit();
// Return the result from this response
return result;
}
/**
* Set the content type
*
* @param value The content type
*/
public void setContentType(String value) {
if (log.isDebugEnabled()) {
log.debug("ContentType: " + value);
}
super.setContentType(value);
result.setContentType(value);
}
/**
* Set the date of a header
*
* @param name The header name
* @param value The date
*/
public void setDateHeader(String name, long value) {
if (log.isDebugEnabled()) {
log.debug("dateheader: " + name + ": " + value);
}
// only set the last modified value, if a complete page is cached
if ((lastModified != CacheFilter.LAST_MODIFIED_OFF) && (CacheFilter.HEADER_LAST_MODIFIED.equalsIgnoreCase(name))) {
if (!fragment) {
result.setLastModified(value);
} // TODO should we return now by fragments to avoid putting the header to the response?
}
// implement RFC 2616 14.21 Expires (without max-age)
if ((expires != CacheFilter.EXPIRES_OFF) && (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name))) {
if (!fragment) {
result.setExpires(value);
} // TODO should we return now by fragments to avoid putting the header to the response?
}
super.setDateHeader(name, value);
}
/**
* Add the date of a header
*
* @param name The header name
* @param value The date
*/
public void addDateHeader(String name, long value) {
if (log.isDebugEnabled()) {
log.debug("dateheader: " + name + ": " + value);
}
// only set the last modified value, if a complete page is cached
if ((lastModified != CacheFilter.LAST_MODIFIED_OFF) && (CacheFilter.HEADER_LAST_MODIFIED.equalsIgnoreCase(name))) {
if (!fragment) {
result.setLastModified(value);
} // TODO should we return now by fragments to avoid putting the header to the response?
}
// implement RFC 2616 14.21 Expires (without max-age)
if ((expires != CacheFilter.EXPIRES_OFF) && (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name))) {
if (!fragment) {
result.setExpires(value);
} // TODO should we return now by fragments to avoid putting the header to the response?
}
super.addDateHeader(name, value);
}
/**
* Set a header field
*
* @param name The header name
* @param value The header value
*/
public void setHeader(String name, String value) {
if (log.isDebugEnabled()) {
log.debug("header: " + name + ": " + value);
}
if (CacheFilter.HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) {
result.setContentType(value);
}
if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) {
result.setContentEncoding(value);
}
super.setHeader(name, value);
}
/**
* Add a header field
*
* @param name The header name
* @param value The header value
*/
public void addHeader(String name, String value) {
if (log.isDebugEnabled()) {
log.debug("header: " + name + ": " + value);
}
if (CacheFilter.HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) {
result.setContentType(value);
}
if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) {
result.setContentEncoding(value);
}
super.addHeader(name, value);
}
/**
* Set the int value of the header
*
* @param name The header name
* @param value The int value
*/
public void setIntHeader(String name, int value) {
if (log.isDebugEnabled()) {
log.debug("intheader: " + name + ": " + value);
}
super.setIntHeader(name, value);
}
/**
* We override this so we can catch the response status. Only
* responses with a status of 200 (<code>SC_OK</code>) will
* be cached.
*/
public void setStatus(int status) {
super.setStatus(status);
this.status = status;
}
/**
* We override this so we can catch the response status. Only
* responses with a status of 200 (<code>SC_OK</code>) will
* be cached.
*/
public void sendError(int status, String string) throws IOException {
super.sendError(status, string);
this.status = status;
}
/**
* We override this so we can catch the response status. Only
* responses with a status of 200 (<code>SC_OK</code>) will
* be cached.
*/
public void sendError(int status) throws IOException {
super.sendError(status);
this.status = status;
}
/**
* We override this so we can catch the response status. Only
* responses with a status of 200 (<code>SC_OK</code>) will
* be cached.
*/
public void setStatus(int status, String string) {
super.setStatus(status, string);
this.status = status;
}
/**
* We override this so we can catch the response status. Only
* responses with a status of 200 (<code>SC_OK</code>) will
* be cached.
*/
public void sendRedirect(String location) throws IOException {
this.status = SC_MOVED_TEMPORARILY;
super.sendRedirect(location);
}
/**
* Retrieves the captured HttpResponse status.
*/
public int getStatus() {
return status;
}
/**
* Set the locale
*
* @param value The locale
*/
public void setLocale(Locale value) {
super.setLocale(value);
result.setLocale(value);
}
/**
* Get an output stream
*
* @throws IOException
*/
public ServletOutputStream getOutputStream() throws IOException {
// Pass this faked servlet output stream that captures what is sent
if (cacheOut == null) {
cacheOut = new SplitServletOutputStream(result.getOutputStream(), super.getOutputStream());
}
return cacheOut;
}
/**
* Get a print writer
*
* @throws IOException
*/
public PrintWriter getWriter() throws IOException {
if (cachedWriter == null) {
String encoding = getCharacterEncoding();
if (encoding != null) {
cachedWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), encoding));
} else { // using the default character encoding
cachedWriter = new PrintWriter(new OutputStreamWriter(getOutputStream()));
}
}
return cachedWriter;
}
/**
* Flushes all streams.
* @throws IOException
*/
private void flush() throws IOException {
if (cacheOut != null) {
cacheOut.flush();
}
if (cachedWriter != null) {
cachedWriter.flush();
}
}
public void flushBuffer() throws IOException {
super.flushBuffer();
flush();
}
/**
* Returns a boolean indicating if the response has been committed.
* A commited response has already had its status code and headers written.
*
* @see javax.servlet.ServletResponseWrapper#isCommitted()
*/
public boolean isCommitted() {
return super.isCommitted(); // || (result.getOutputStream() == null);
}
/**
* Clears any data that exists in the buffer as well as the status code and headers.
* If the response has been committed, this method throws an IllegalStateException.
* @see javax.servlet.ServletResponseWrapper#reset()
*/
public void reset() {
log.info("CacheHttpServletResponseWrapper:reset()");
super.reset();
/*
cachedWriter = null;
result = new ResponseContent();
cacheOut = null;
fragment = false;
status = SC_OK;
expires = CacheFilter.EXPIRES_ON;
lastModified = CacheFilter.LAST_MODIFIED_INITIAL;
cacheControl = -60;
// time ?
*/
}
/**
* Clears the content of the underlying buffer in the response without clearing headers or status code.
* If the response has been committed, this method throws an IllegalStateException.
* @see javax.servlet.ServletResponseWrapper#resetBuffer()
*/
public void resetBuffer() {
log.info("CacheHttpServletResponseWrapper:resetBuffer()");
super.resetBuffer();
/*
//cachedWriter = null;
result = new ResponseContent();
//cacheOut = null;
//fragment = false;
*/
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?