PageCacheFilter2
Posted on December 31, 2007 - Filed Under Uncategorized |
最近翻起一年多前在上一家公司写的代码,发现也有不少工具性质的类,于是整理一下都贴出来吧
/** * 2006-5-1 * @author Sparkle */ public class PageCacheFilter2 implements Filter { private Set<String> cacheUrlSet = new HashSet<String>(); private Set<String> scacheUrlSet = new HashSet<String>(); private String baseCachePath, contentType; public void init(FilterConfig config) throws ServletException { String cacheUrl = config.getInitParameter("cacheUrl"); if (cacheUrl != null) { StringTokenizer tk = new StringTokenizer(cacheUrl); while (tk.hasMoreTokens()) { String str = tk.nextToken().trim().toLowerCase(); if (str.endsWith("?")) { str = str.substring(0, str.length() - 1); scacheUrlSet.add(str); } cacheUrlSet.add(str); } } baseCachePath = config.getInitParameter("cachePath"); contentType = config.getInitParameter("contentType"); } private int urlHashCode(HttpServletRequest request) { String uri = request.getRequestURI(); String qStr = request.getQueryString(); if (qStr != null) { uri += ('?' + qStr); } return Math.abs(uri.hashCode()); } private String cacheFilePath(HttpServletRequest request) { String uri = request.getRequestURI(); int hash = urlHashCode(request); if (scacheUrlSet.contains(uri.toLowerCase())) { String entityId = request.getParameter("entityId"); if (StringUtils.isNotBlank(entityId)) { return baseCachePath + "/article/" + subDir(entityId) + '/' + entityId + '/' + hash + ".wml"; } } return baseCachePath + "/other/" + subDir2(String.valueOf(hash)) + '/' + hash + ".wml"; } private String subDir(String str) { int length = str.length(); if (length > 4) { return str.substring(0, length - 4); } return "0"; } private String subDir2(String str) { int length = str.length(); if (length > 4) { return str.substring(length - 4, length); } return str; } private void clearCache(HttpServletRequest request, File cacheFile) { if (scacheUrlSet.contains(request.getRequestURI().toLowerCase())) { File cacheDir = cacheFile.getParentFile(); for (File file : cacheDir.listFiles()) { file.delete(); } cacheDir.delete(); } else { cacheFile.delete(); } } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; if (!cacheUrlSet.contains(request.getRequestURI().toLowerCase())) { chain.doFilter(req, res); return; } HttpServletResponse response = (HttpServletResponse) res; File cacheFile = new File(cacheFilePath(request)); if (cacheFile.isFile()) { if (request.getParameter("refresh") != null) { clearCache(request, cacheFile); } else { try { BufferedReader reader = new BufferedReader( new FileReader(cacheFile)); response.setContentType(contentType); String line; PrintWriter printWriter = response.getWriter(); while ((line = reader.readLine()) != null) { printWriter.println(line); } printWriter.close(); return; } catch (IOException e) { // ignore response.reset(); System.out.println("read cache file error"); } } } StringWriter strWriter = new StringWriter(); boolean[] support = new boolean[1]; support[0] = true; chain.doFilter(req, new ContentResponseWrapper(response, strWriter, support)); if (support[0] && !response.isCommitted()) { String content = strWriter.getBuffer().toString(); PrintWriter printWriter = response.getWriter(); printWriter.println(content); printWriter.close(); File cacheDir = cacheFile.getParentFile(); if (!cacheDir.exists()) { cacheDir.mkdirs(); } PrintWriter writer = new PrintWriter(cacheFile); writer.println(content); writer.close(); } } public void destroy() { } }
代码点评:这段代码的作用是,对指定的url进行cache,用了ContentRewriteFilter一样的做法来获取内容,因为具体的细节有些区别,没有继承ContentRewriteFilter而是直接编写代码。先判断是否有cache文件,如果有就输出给用户,但是如果连接上有refresh参数的话,就会清掉cache文件,如果没有cache文件,就会获取Servlet or JSP输出的内容,原原本本保存到磁盘,供下次用户访问使用。如果设置URL的时候,最后一位是问号,就会进入scacheUrlSet,这个是用于文章类型,主要的不同点是有分页,如果要refresh的话,应该要把所有分页的cache文件都清除。至于类名后面有个2,是因为这个是第二个版本。
(最近在考虑用Squid+Etag来实现一样的功能)
Related Post
Comments
Leave a Reply