您的位置:首页 > 其它

关于使用脚本请求服务器端资源无法缓存的问题

2007-04-23 09:59 716 查看
在使用脚本请求服务器端资源时(如图片),会出现重复下载资源的问题,这个问题只在IE中出现过,经查找,发现一个解决方式:加一个过滤器,代码如下:、

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Filter fixes the IE image cache bug described at folowing locations.
* http://mir.aculo.us/articles/2005/08/28/internet-explorer-and-ajax-image-caching-woes * http://www.netmechanic.com/news/vol6/javascript_no1.htm * http://www.bazon.net/mishoo/articles.epl?art_id=958 * http://ahinea.com/en/tech/ie-dhtml-image-caching.html *
* @author zluspai
*/
public class IEImageCacheBugFixFilter implements Filter {

private static final Log LOG = LogFactory.getLog(IEImageCacheBugFixFilter.class);
// if the slowness is simulated by this filter
private static final boolean SIMULATE_SLOWNESS = false;

// date format for header
private static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("EEE, d MMM yyyy 00:00:00 z", Locale.US);;

// regexp Pattern objects precompiled
private List patterns = new ArrayList();

/**
* {@inheritDoc}
*/
public void init(FilterConfig config) throws ServletException {
String patternParam = config.getInitParameter("patterns");
// parse patterns
if (patternParam != null) {
String[] patternArr = patternParam.split(",");
for (int i = 0; i < patternArr.length; i++) {
String pattern = patternArr[i];
try {
Pattern p = Pattern.compile(pattern);
this.patterns.add(p);
} catch (PatternSyntaxException syntaxex) {
LOG.warn("Exception when parsing pattern:" + pattern, syntaxex);
}
}
}
}

/**
* Check if the path matches with the regexp patterns.
*
* @param path The path string
* @return If matched
*/
private boolean isMatch(String path) {
for (Iterator iPatterns = patterns.iterator(); iPatterns.hasNext();) {
Pattern pattern = (Pattern) iPatterns.next();
if (pattern.matcher(path).matches()) {
if (LOG.isDebugEnabled()) {
LOG.debug("matched: " + pattern.pattern() + " ,path:" + path);
}
return true;
}
}
return false;
}

/**
* {@inheritDoc}
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String path = httpRequest.getRequestURI();

// check patterns
if (isMatch(path)) {
if (LOG.isDebugEnabled()) {
LOG.debug(getHeaderInfo(httpRequest));
}

// check if the browser asks if-modified
if (httpRequest.getHeader("if-modified-since") != null) {
// tell the browser that resource not changed, so it can use
// the cached version!
httpResponse.setStatus(304);
LOG.debug("returning 304 for path:" + path);
return;
}

// uncomment this to simulate slow response
if (SIMULATE_SLOWNESS) {
delay(path);
}
// turn on caching for everything served:
addCacheHeader(httpResponse, path);
}
}
// forward in chain
chain.doFilter(request, response);
}

/**
* Add cache header to the response.
*
* @param httpResponse The response
* @param path The current path
*/
private void addCacheHeader(HttpServletResponse httpResponse, String path) {
httpResponse.setHeader("Cache-control", "max-age=10000000");
Calendar c = Calendar.getInstance();
String date = DATEFORMAT.format(c.getTime());
httpResponse.setHeader("Last-Modified", date);
// expires is one more year:
c.add(Calendar.YEAR, 1);
date = DATEFORMAT.format(c.getTime());
httpResponse.setHeader("Expires", date);
// unique tag needed
httpResponse.setHeader("ETag", path);
}

/**
* Log header info arrived in request.
*
* @param httpRequest The HttpRequest object.
* @return String containig all header info.
*/
private String getHeaderInfo(HttpServletRequest httpRequest) {
StringBuffer info = new StringBuffer();
Enumeration headernames = httpRequest.getHeaderNames();
while (headernames.hasMoreElements()) {
String name = (String) headernames.nextElement();
info.append(name + "=" + httpRequest.getHeader(name)).append("/n");
}
return info.toString();
}

/**
* Implemented Filter method.
*/
public void destroy() {
}

/**
* Delay a bit before serving the response.
*
* @param path The current request url path
*/
private void delay(String path) {
// long delay:
try {
LOG.info("Waiting before serving of:" + path);
Thread.sleep(2000);
} catch (InterruptedException e) {
LOG.debug("ignored exception", e);
}
}

}


To use this filter you will need to map it in the web.xml, for example:



<!-- fixes IE caching problem for Ajax requests -->
<!-- several directories can be cached: dojo, customdoj, images, scripts -->
<filter>
<filter-name>IEImageCacheBugFixFilter</filter-name>
<filter-class>IEImageCacheBugFixFilter</filter-class>
<init-param>
<param-name>patterns</param-name>
<param-value>.*/.(g|G)(i|I)(f|F),.*/.(j|J)(p|P)(g|G),.*/dojo/.*,.*/images/.*,.*/scripts/.*,</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>IEImageCacheBugFixFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐