首页 web前端 html教程 借助Ehcache缓存框架实现对页面的缓存_html/css_WEB-ITnose

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

Jun 24, 2016 am 11:47 AM

        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分下载该示例】

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

HTML5中跨浏览器兼容性的最佳实践是什么? HTML5中跨浏览器兼容性的最佳实践是什么? Mar 17, 2025 pm 12:20 PM

文章讨论了确保HTML5跨浏览器兼容性的最佳实践,重点是特征检测,进行性增强和测试方法。

&gt; gt;的目的是什么 元素? &gt; gt;的目的是什么 元素? Mar 21, 2025 pm 12:34 PM

本文讨论了HTML&lt; Progress&gt;元素,其目的,样式和与&lt; meter&gt;元素。主要重点是使用&lt; progress&gt;为了完成任务和LT;仪表&gt;对于stati

&lt; datalist&gt;的目的是什么。 元素? &lt; datalist&gt;的目的是什么。 元素? Mar 21, 2025 pm 12:33 PM

本文讨论了html&lt; datalist&gt;元素,通过提供自动完整建议,改善用户体验并减少错误来增强表格。Character计数:159

如何使用HTML5表单验证属性来验证用户输入? 如何使用HTML5表单验证属性来验证用户输入? Mar 17, 2025 pm 12:27 PM

本文讨论了使用HTML5表单验证属性,例如必需的,图案,最小,最大和长度限制,以直接在浏览器中验证用户输入。

&lt; meter&gt;的目的是什么。 元素? &lt; meter&gt;的目的是什么。 元素? Mar 21, 2025 pm 12:35 PM

本文讨论了HTML&lt; meter&gt;元素,用于在一个范围内显示标量或分数值及其在Web开发中的常见应用。它区分了&lt; meter&gt;从&lt; progress&gt;和前

视口元标签是什么?为什么对响应式设计很重要? 视口元标签是什么?为什么对响应式设计很重要? Mar 20, 2025 pm 05:56 PM

本文讨论了视口元标签,这对于移动设备上的响应式Web设计至关重要。它解释了如何正确使用确保最佳的内容缩放和用户交互,而滥用可能会导致设计和可访问性问题。

&lt; iframe&gt;的目的是什么。 标签?使用时的安全考虑是什么? &lt; iframe&gt;的目的是什么。 标签?使用时的安全考虑是什么? Mar 20, 2025 pm 06:05 PM

本文讨论了&lt; iframe&gt;将外部内容嵌入网页,其常见用途,安全风险以及诸如对象标签和API等替代方案的目的。

HTML容易为初学者学习吗? HTML容易为初学者学习吗? Apr 07, 2025 am 12:11 AM

HTML适合初学者学习,因为它简单易学且能快速看到成果。1)HTML的学习曲线平缓,易于上手。2)只需掌握基本标签即可开始创建网页。3)灵活性高,可与CSS和JavaScript结合使用。4)丰富的学习资源和现代工具支持学习过程。

See all articles