登录  /  注册

借助Ehcache缓存框架实现对页面的缓存_html/css_WEB-ITnose

php中文网
发布: 2016-06-24 11:47:30
原创
1331人浏览过

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

        工程结构:


        代码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文件代码:

<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation="ehcache.xsd" updatecheck="true" monitoring="autodetect" dynamicconfig="true"><!-- 		diskStore :指定数据存储位置,可指定磁盘中的文件夹位置 		--><diskstore path="java.io.tmpdir/ehcache"></diskstore><!--		defaultCache: 默认的管理策略		diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。 		diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。		--><defaultcache maxentrieslocalheap="10000" maxentrieslocaldisk="10000000" eternal="false" timetoidleseconds="120" timetoliveseconds="120" overflowtodisk="true" diskspoolbuffersizemb="30" diskpersistent="false" diskexpirythreadintervalseconds="120" memorystoreevictionpolicy="LRU"></defaultcache><!--配置自定义缓存: 		name: Cache的名称,具有唯一性,Ehcache会把该cache放到HashMap里。		maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制		maxEntriesLocalDisk:磁盘中的最大对象数,默认为0不限制		eternal:设定缓存中elements是否永久有效,如果为true,timeouts设置将被忽略,element将永不过期;如果为false,则需要根据timeToIdleSeconds和timeToLiveSeconds相关配置进行判断。 		overflowToDisk:内存中数据超过设定的内存限制,造成内存不足时, 是否启用磁盘缓存以将数据缓存到磁盘上。。 		diskSpoolBufferSizeMB:设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个cache使用各自的DiskStore。		timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效(即将eternal设为false时), 如果该值是 0 就意味着元素可以停顿无穷长的时间。 		timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值, 这只能在元素不是永久驻留时有效(即将eternal设为false时),如果该值是0就意味着元素可以停顿无穷长的时间。 		memoryStoreEvictionPolicy:内存中数据超过设定的内存限制,造成内存不足时,该Cache启用的内存回收策略,默认值为LRU,可选FIFO、LFU。		Ehcache三大内存回收策略:		FIFO:First In First Out (先进先出)。		LFU: Less Frequently Used (最少被使用的)??所缓存的元素有一个hit属性,hit值最小的将会被“优先”清出缓存。		LRU:Least Recently Used(最近最少使用)??缓存的元素有一个时间戳,当缓存容量满了而又需要腾出地方来缓存新的元素时,那么现有缓存元素中时间戳离当前时间最远的元素将被“优先”清出缓存。		 --><cache name="PageEhCacheFilter" maxentrieslocalheap="10000" maxentrieslocaldisk="1000" eternal="false" overflowtodisk="true" diskspoolbuffersizemb="20" timetoidleseconds="5" timetoliveseconds="10" memorystoreevictionpolicy="LFU"></cache></ehcache>
登录后复制

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

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

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

log4j.rootLogger=DEBUG,Console,DailyRollingFilelog4j.appender.Console=org.apache.log4j.ConsoleAppenderlog4j.appender.Console.layout=org.apache.log4j.PatternLayoutlog4j.appender.Console.layout.ConversionPattern= [%-5p]-[%d{yyyy-MM-dd HH:mm:ss}] -%l -%m%nlog4j.appender.DailyRollingFile=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.DailyRollingFile.Encoding=UTF-8log4j.appender.DailyRollingFile.File=C\:\\framework.loglog4j.appender.DailyRollingFile.DatePattern=yyyy-MM-dd'.log'log4j.appender.DailyRollingFile.layout=org.apache.log4j.PatternLayoutlog4j.appender.DailyRollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n
登录后复制

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

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd " version="2.5"><!-- 配置缓存并gzip压缩页面数据的核心过滤器 --><filter><filter-name>PageEhCacheFilter</filter-name><filter-class>com.ghj.packageoffilter.PageEhCacheFilter</filter-class><!-- 需要缓存的页面url --><init-param><param-name>patterns</param-name><param-value>/index.jsp</param-value></init-param><!-- 配置该过滤器所使用的Dhcache,值得注意的是:也可以不配置cacheName属性,但这时“ehcache.xml”文件中第44行代码的name属性必须为SimplePageCachingFilter,因为PageEhCacheFilter类继承的SimplePageCachingFilter类中设定了cacheName的值为“SimplePageCachingFilter”;如果在这里指定了cacheName属性,那么“ehcache.xml”文件中第44行代码的name属性的属性值必须和所配置的一致--><init-param><param-name>cacheName</param-name><param-value>PageEhCacheFilter</param-value></init-param></filter><filter-mapping><filter-name>PageEhCacheFilter</filter-name><url-pattern>*.action</url-pattern></filter-mapping><filter-mapping><filter-name>PageEhCacheFilter</filter-name><url-pattern>*.jsp</url-pattern></filter-mapping></web-app>
登录后复制

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

			<title>首页</title><div style="text-align:center;margin-top:360px;">			<font style="color:green;font-weight:bold;font-size: 18px"></font><br><br><font style="color:red;font-weight:bold;font-size: 27px">每次刷新页面,如果时间是变动的,则说明该页面没有被缓存或缓存已经过期,否则则说明该页面已经被缓存。</font>		</div>	
登录后复制

        【0分下载该示例】

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号