使用Ehcache给页面做缓存
一.准备相关文件
1.下载 JAR包
使用Ehcache做页面的缓存,所以只需要下载 ehcache-core和ehcache-web模块
ehcache 下载地址:http://ehcache.org/modules
2.将jar复制到lib文件夹
ehcache-core-XXX.jar
ehcache-web-XXX.jar 主要针对页面缓存
3.复制配置文件
复制 ehcache.xml 到 src 目录。保证编译后会复制到web-inf/classes下面
<?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 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 指向一个cachingFiter,默认使用 SimplePageCachingFilter就够用了。
-->
<cache name="SimplePageCachingFilter"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" />
</ehcache>
二.写FILTER对路径进行拦截。
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.yhl.jfinal_helloword.cache;
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;
/**
* 页面缓存过滤器
* @version 1.0
* @author YHL
*/
public class PageEhCacheFilter extends SimplePageCachingFilter{
private final static Logger log = Logger.getLogger(PageEhCacheFilter.class);
private final static String FILTER_URL_PATTERNS = "patterns"; //WEB.XML中配置要过滤的地址
private static String[] cacheURLs;
private static boolean cache_index=false;
private void init() throws CacheException {
String patterns = filterConfig.getInitParameter(FILTER_URL_PATTERNS);
cacheURLs = StringUtils.split(patterns, ",");
}
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();
String url = request.getServletPath();
boolean flag = false;
if (cacheURLs != null && cacheURLs.length > 0) {
for (String cacheURL : cacheURLs) {
if (url.startsWith(cacheURL.trim())) {
flag = true;
break;
}
}
}
//
// 如果包含我们要缓存的url 就缓存该页面,否则执行正常的页面转向
if (flag) {
String query = request.getQueryString();
if ( !StringUtils.isBlank( query )) {
query = "?" + query;
}
log.info("当前请求被缓存:" + url + (!StringUtils.isBlank(query)&& !query.equalsIgnoreCase("null")?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;
}
/**
* 兼容ie6、7 使用gzip压缩
*/
@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;
}
}
三.配置web.xml
注意:一定要将ehcache的filter 配置在 其他 filter之前。
还有注意filter-class的包名和文件名。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<!-- 缓存、gzip压缩核心过滤器 -->
<filter>
<filter-name>PageEhCacheFilter</filter-name>
<filter-class>com.yhl.jfinal_helloword.cache.PageEhCacheFilter</filter-class>
<init-param>
<description>使用绝对路径进行匹配。url.starWith(缓存路径)</description>
<param-name>patterns</param-name>
<param-value>/hello,/index.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PageEhCacheFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>com.yhl.jfinal_helloword.config.DemoConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 缓存配置结束 -->
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
四.测试
如果是动态页面,可以根据页面变化来判断是否缓存。
也可以在jsp中添加<%=new Date()%> 通过刷新页面,看时间的变化进行判断。