借助Ehcache缓存框架实现对页面的缓存

        Ehcache是一个纯Java进程内缓存框架,该内存框架可以实现对页面或对象等数据的缓存——可以将数据缓存到内存和磁盘;与Memacached一样,该框架也支持集群/分布式缓存。本片博客用于研究如何借助Ehcache缓存框架实现对页面的缓存。页面缓存主要用Filter过滤器对客户端的http请求进行过滤,如果该请求存在于缓存中,那么页面将从缓存对象中获取gzip压缩后的数据(其响应速度是没有压缩缓存时速度的3-5倍)。页面缓存的过滤器有CachingFilter,可以通过继承该CachingFilter实现自定义页面缓存过滤器(Ehcache自身封装的SimplePageCachingFilter类就是通过继承CachingFilter类实现的页面缓存过滤器)。下面与大家分享一个示例:

        工程结构:

借助Ehcache缓存框架实现对页面的缓存_第1张图片

        代码1——PageEhCacheFilter.java文件代码:

package com.ghj.packageoffilter;
 
import java.util.Enumeration;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.ehcache.constructs.blocking.LockTimeoutException;
import net.sf.ehcache.constructs.web.AlreadyCommittedException;
import net.sf.ehcache.constructs.web.AlreadyGzippedException;
import net.sf.ehcache.constructs.web.filter.FilterNonReentrantException;
import net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * 页面缓存过滤器
 * 
 * @author 高焕杰
 */
public class PageEhCacheFilter extends SimplePageCachingFilter {

    private final static Logger logger = Logger.getLogger(PageEhCacheFilter.class);

    private static String[] cacheURLArray;

    @Override
    protected void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws AlreadyGzippedException, AlreadyCommittedException, FilterNonReentrantException, LockTimeoutException, Exception {
        if (cacheURLArray == null) {
        	String patterns = filterConfig.getInitParameter("patterns");
        	cacheURLArray = StringUtils.split(patterns, ",");
        }
        
        String requestURL = request.getRequestURL().toString();
        boolean containCacheURLFlag = false;
        if (cacheURLArray != null && cacheURLArray.length > 0) {
            for (String cacheURL : cacheURLArray) {
                if (requestURL.contains(cacheURL.trim())) {//判断当前请求是否是要缓存的url
                	containCacheURLFlag = true;
                    break;
                }
            }
        }

        if (containCacheURLFlag) {//当前请求是要缓存的url
            String queryString = request.getQueryString();
            if (StringUtils.isNotEmpty(queryString)) {//当前请求含有采用问号传过来的参数
            	queryString = "?" + queryString;
            	logger.info("当前请求被缓存:" + requestURL + queryString);
            }else{
            	logger.info("当前请求被缓存:" + requestURL);
            }
            super.doFilter(request, response, chain);
        } else {//当前请求不是要缓存的url
            chain.doFilter(request, response);
        }
    }

    /**
     * 重写acceptsGzipEncoding方法,使该过滤器兼容对客户使用IE6和IE7时发过来请求时的gzip压缩
     * 使用Gzip压缩时,需注意两个问题:
	 * 1、Filter进行Gzip压缩时,采用系统默认编码方式,对于使用GBK编码的中文网页来说,需要将操作系统的语言设置为“zh_CN.GBK”,否则会出现乱码问题。
	 * 2、默认情况下CachingFilter类(SimplePageCachingFilter类的父类)会根据浏览器发送的请求头部所包含的Accept-Encoding参数值来判断是否进行Gzip压缩。虽然浏览器IE6和IE7支持Gzip压缩,但是在发送请求的时候却不带该参数,因此可以通过继承CachingFilter类,重写acceptsGzipEncoding方法来实现。
     *
     * @author 高焕杰
     */
    @Override
    protected boolean acceptsGzipEncoding(HttpServletRequest request) {
        boolean ie6 = headerContains(request, "User-Agent", "MSIE 6.0");
        boolean ie7 = headerContains(request, "User-Agent", "MSIE 7.0");
        return acceptsEncoding(request, "gzip") || ie6 || ie7;
    }

    private boolean headerContains(final HttpServletRequest request, final String header, final String value) {
        logRequestHeaders(request);
        final Enumeration accepted = request.getHeaders(header);
        while (accepted.hasMoreElements()) {
            final String headerValue = (String) accepted.nextElement();
            if (headerValue.indexOf(value) != -1) {
                return true;
            }
        }
        return false;
    }
}

        代码2——ehcache.xml文件代码:




	
	

	
	

	
	

        代码3——ehcache.xsd文件代码:

        该文件取自该压缩文件中——【0分下载该压缩文件

        代码4——log4j.properties文件代码:

log4j.rootLogger=DEBUG,Console,DailyRollingFile

log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern= [%-5p]-[%d{yyyy-MM-dd HH:mm:ss}] -%l -%m%n

log4j.appender.DailyRollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DailyRollingFile.Encoding=UTF-8
log4j.appender.DailyRollingFile.File=C\:\\framework.log
log4j.appender.DailyRollingFile.DatePattern=yyyy-MM-dd'.log'
log4j.appender.DailyRollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.DailyRollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n

        代码5——web.xml文件代码:




	
	
		PageEhCacheFilter
		com.ghj.packageoffilter.PageEhCacheFilter
		
		
			patterns
			/index.jsp
		
		
		
		
			cacheName
			PageEhCacheFilter
		
	

	
		PageEhCacheFilter
		*.action
	
	
		PageEhCacheFilter
		*.jsp
	

        代码6——index.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Date,java.text.SimpleDateFormat"%>


	
		首页
	
	
	
		
<%=new SimpleDateFormat("yyyy-MM-dd hh:MM:ss").format(new Date())%>

每次刷新页面,如果时间是变动的,则说明该页面没有被缓存或缓存已经过期,否则则说明该页面已经被缓存。

        【0分下载该示例

你可能感兴趣的:(Ehcache)