缓存插件 EHCache 页面缓存CachingFilter
Ehcache基本用法
CacheManager cacheManager = CacheManager.create();
// 或者
cacheManager = CacheManager.getInstance();
// 或者
cacheManager = CacheManager.create("/config/ehcache.xml");
// 或者
cacheManager = CacheManager.create("http://localhost:8080/test/ehcache.xml");
cacheManager = CacheManager.newInstance("/config/ehcache.xml");
// ....... // 获取ehcache配置文件中的一个cache
Cache sample = cacheManager.getCache("sample");
// 获取页面缓存
BlockingCache cache = new BlockingCache(cacheManager.getEhcache("SimplePageCachingFilter"));
// 添加数据到缓存中
Element element = new Element("key", "val");
sample.put(element);
// 获取缓存中的对象,注意添加到cache中对象要序列化 实现Serializable接口
Element result = sample.get("key");
// 删除缓存
sample.remove("key");
sample.removeAll(); // 获取缓存管理器中的缓存配置名称
for (String cacheName : cacheManager.getCacheNames()) {
System.out.println(cacheName);
}
// 获取所有的缓存对象
for (Object key : cache.getKeys()) {
System.out.println(key);
} // 得到缓存中的对象数
cache.getSize();
// 得到缓存对象占用内存的大小
cache.getMemoryStoreSize();
// 得到缓存读取的命中次数
cache.getStatistics().getCacheHits();
// 得到缓存读取的错失次数
cache.getStatistics().getCacheMisses();
页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。
CachingFilter功能可以对HTTP响应的内容进行缓存。这种方式缓存数据的粒度比较粗,例如缓存整张页面。它的优点是使用简单、效率高,缺点是不够灵活,可重用程度不高。
EHCache使用SimplePageCachingFilter类实现Filter缓存。该类继承自CachingFilter,有默认产生cache key的calculateKey()方法,该方法使用HTTP请求的URI和查询条件来组成key。也可以自己实现一个Filter,同样继承CachingFilter类,然后覆写calculateKey()方法,生成自定义的key。
CachingFilter输出的数据会根据浏览器发送的Accept-Encoding头信息进行Gzip压缩。
在使用Gzip压缩时,需注意两个问题:
1. Filter在进行Gzip压缩时,采用系统默认编码,对于使用GBK编码的中文网页来说,需要将操作系统的语言设置为:zh_CN.GBK,否则会出现乱码的问题。
2. 默认情况下CachingFilter会根据浏览器发送的请求头部所包含的Accept-Encoding参数值来判断是否进行Gzip压缩。虽然IE6/7浏览器是支持Gzip压缩的,但是在发送请求的时候却不带该参数。为了对IE6/7也能进行Gzip压缩,可以通过继承CachingFilter,实现自己的Filter,然后在具体的实现中覆写方法acceptsGzipEncoding。
具体实现参考:
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;
}
在ehcache.xml中加入如下配置
<?xml version="1.0" encoding="gbk"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
<!--
配置自定义缓存
maxElementsInMemory:缓存中允许创建的最大对象数
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,
这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
-->
<cache name="SimplePageCachingFilter"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" /> </ehcache>
具体代码:
package com.hoo.ehcache.filter; import java.util.Enumeration;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.ehcache.CacheException;
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; /**
* <b>function:</b> mobile 页面缓存过滤器
* @author hoojo
* @createDate 2012-7-4 上午09:34:30
* @file PageEhCacheFilter.java
* @package com.hoo.ehcache.filter
* @project Ehcache
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class PageEhCacheFilter extends SimplePageCachingFilter { private final static Logger log = Logger.getLogger(PageEhCacheFilter.class); private final static String FILTER_URL_PATTERNS = "patterns";
private static String[] cacheURLs; private void init() throws CacheException {
String patterns = filterConfig.getInitParameter(FILTER_URL_PATTERNS);
cacheURLs = StringUtils.split(patterns, ",");
} @Override
protected void doFilter(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain chain)
throws AlreadyGzippedException, AlreadyCommittedException,
FilterNonReentrantException, LockTimeoutException, Exception {
if (cacheURLs == null) {
init();
} String url = request.getRequestURI();
boolean flag = false;
if (cacheURLs != null && cacheURLs.length > 0) {
for (String cacheURL : cacheURLs) {
if (url.contains(cacheURL.trim())) {
flag = true;
break;
}
}
}
// 如果包含我们要缓存的url 就缓存该页面,否则执行正常的页面转向
if (flag) {
String query = request.getQueryString();
if (query != null) {
query = "?" + query;
}
log.info("当前请求被缓存:" + url + query);
super.doFilter(request, response, chain);
} else {
chain.doFilter(request, response);
}
} @SuppressWarnings("unchecked")
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;
} /**
* @see net.sf.ehcache.constructs.web.filter.Filter#acceptsGzipEncoding(javax.servlet.http.HttpServletRequest)
* <b>function:</b> 兼容ie6/7 gzip压缩
* @author hoojo
* @createDate 2012-7-4 上午11:07:11
*/
@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;
}
}
这里的PageEhCacheFilter继承了SimplePageCachingFilter,一般情况下SimplePageCachingFilter就够用了,这里是为了满足当前系统需求才做了覆盖操作。使用SimplePageCachingFilter需要在web.xml中配置cacheName,cacheName默认是SimplePageCachingFilter,对应ehcache.xml中的cache配置。
在web.xml中加入如下配置
<!-- 缓存、gzip压缩核心过滤器 -->
<filter>
<filter-name>PageEhCacheFilter</filter-name>
<filter-class>com.hoo.ehcache.filter.PageEhCacheFilter</filter-class>
<init-param>
<param-name>patterns</param-name>
<!-- 配置你需要缓存的url -->
<param-value>/cache.jsp, product.action, market.action </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>
当第一次请求这些页面后,这些页面就会被添加到缓存中,以后请求这些页面将会从缓存中获取。你可以在cache.jsp页面中用小脚本来测试该页面是否被缓存。<%=new Date()%>如果时间是变动的,则表示该页面没有被缓存或是缓存已经过期,否则则是在缓存状态了。
缓存插件 EHCache 页面缓存CachingFilter的更多相关文章
- 缓存插件 EHCache 对象缓存(Spring)
对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询. 对象缓存一般是针对方法.类而来的,结合Spring的Aop对象.方法缓存就很简单.这里需要用到切面编程 ...
- 缓存插件 EHCache
EHCache是来自sourceforge(http://ehcache.sourceforge.net/)的开源项目,也是纯Java实现的简单.快速的Cache组件. 下载jar包 Ehcache ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- MVC3缓存:使用页面缓存
在以前的WebForm的开发中,在页面的头部加上OutputCache即可启用页面缓存,而在MVC3中,使用了Razor模板引擎的话,该如何使用页面缓存呢?如何启用 在MVC3中要如果要启用页面缓存, ...
- [转载]MVC3缓存:使用页面缓存
在以前的WebForm的开发中,在页面的头部加上OutputCache即可启用页面缓存,而在MVC3中,使用了Razor模板引擎的话,该如何使用页面缓存呢?如何启用 在MVC3中要如果要启用页面缓存, ...
- 缓存:前端页面缓存、服务器缓存(依赖SQL)MVC3
缓存依赖数据库 第一步 1通过vs里面带的命令提示窗口. 2或者.NET Framework 版本 4(64 位系统)条件,%windir%\Microsoft.NET\Framework64\v4. ...
- Hibernate缓存策略(一级缓存和EHcache二级缓存)
如何配置二级缓存: 第一步:导入EHcache依赖 1)Maven项目: <!--此处使用hibernate4--> <dependency> <groupId>o ...
- Yii的缓存机制之页面缓存
页面缓存是不能通过片段缓存来实现的,因为布局和内容不能同时缓存.只能通过过滤器来生成缓存. 实现方法: 在控制器里使用过滤器来实现 function filters (){ return array( ...
- yii2.0缓存篇之页面缓存
页面缓存: 如果整个页面都不会发生改变,就可以使用页面缓存缓存整个页面. public function behaviors(){ //此方法[也叫行为]会提前控制器内其他方法执 ...
随机推荐
- [cocos2dx] 让UIButton支持disable状态
摘要: 主要解决cocos2dx-2.2.2版本中, UIButton显示不了disable状态图的问题. 顺便, 理解了一下cocos2dx中UIWidget的渲染原理. 博客: http://ww ...
- LoadRunner支持的IE版本
LoadRunner支持的IE版本: 8.0 最高ie68.1 最高ie69.0 最高ie79.5 最高ie811.0 最高ie9( win7 32位+LR11+IE10可用,但win7 64位+LR ...
- 更改QTP默认测试脚本路径
QTP的默认测试脚本路径为安装路径下的Tests文件夹下, 如果你安装在D:,那么默认脚本路径为D:\Program Files\HP\QuickTest Professional\Tests 但是因 ...
- android stuio eclipse映射下的快捷键
转:关于 android stuio eclipse映射下的快捷键 http://www.cnblogs.com/0616--ataozhijia/p/3870064.html 会持续更新)这边讲的常 ...
- 在centos下部署docker内网私服
Docker内网私服:docker-registry with nginx & ssl on centos docker-registry既然也是软件应用,自然最简单的方法就是使用官方提供的已 ...
- java中的单引号和双引号
1.单引号引的数据 是char类型的,双引号引的数据 是String类型的:单引号只能引一个字符,而双引号可以引0个及其以上.char只是一个基本类型,而String 可以是一个类,可以直接引用.比如 ...
- Gradle的安装
1.Gradle依赖JDK,所以先在机器上安装好JDK,设置好JAVA_HOME与PATH环境变量 2.从官网下载合适的Gradle发行包 3.发行包是一个zip文件,解压后,将 GRADLE_HOM ...
- U5398 改数(num)
U5398 改数(num) 5通过 28提交 题目提供者52zyz 标签 难度尚无评定 提交 最新讨论 暂时没有讨论 题目背景 又是一年NOIP,科学馆的五楼:“我们看下这道题,我们来模拟一下…2,3 ...
- 设置Eclipse中的tab键为4个空格的完整方法
1.点击 window->preference-,依次选择 General->Editors->Text Editors,选中右侧的 insert space for tabs;如下 ...
- 加密算法使用(四):AES的使用
AES是一种对称加密方式,比DES更为安全,用一个秘钥加密数据之后,可以用同一个秘钥对加密后的数据解密还原,以下是一套以字符串为例子的使用全过程演示, 用到了 commons-codec.jar pa ...