Ehcache 页面缓存

Posted 崔耀强

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ehcache 页面缓存相关的知识,希望对你有一定的参考价值。

页面缓存,毫无疑问,几乎所有的网站的首页都是访问率最高的,而首页上的数据来源又是非常广泛的,大多数来自不同的对象,而且有可能来自不同的db ,所以给首页做缓存是一个不错的主意,那么主页的缓存策略是什么样子的呢,我认为应该是某个固定时间之内不变的,比如说2 分钟更新一次。那么这个缓存应该做在什么地方呢,让我们来看一下,假设您的应用的结构是page-filter-action-service-dao-db ,这个过程中的- 的地方都是可以做缓存的地方,根据页面缓存的特征,应该把页面缓存做到尽量靠近客户的地方,就是在page 和filter 之间,这样的优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter 这个请求就结束了,无需再走后面的action-service-dao-db 。带来的好处是服务器压力的减低和客户段页面响应速度的加快。

页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!
其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。

编写页面缓存的步骤如下:
项目结构:
这里写图片描述
1)添加相应的jar,这里写图片描述,这里使用的是2.5的jar。
2)在web.xml中添加缓存过滤器配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>20160623PageCache</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
 <!-- 配置缓存并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>
		
		<!-- 配置该过滤器所使用的ehcache,值得注意的是:也可以不配置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>

3)添加Ehcache的相关配置文件。
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" />

	<!--
		defaultCache: 默认的管理策略
		diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。 
		diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。
		这个Cache不能删除,否则会抛出No default cache is configured异常
		-->
	<defaultCache 
		maxEntriesLocalHeap="10000"
		maxEntriesLocalDisk="10000000"
		eternal="false"
		timeToIdleSeconds="120"
		timeToLiveSeconds="120"
		overflowToDisk="true"
		diskSpoolBufferSizeMB="30"
		diskPersistent="false"
		diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU" />

	<!--配置自定义缓存: 
		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" />
</ehcache>

ehcache.xsd

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.7">

    <xs:element name="ehcache">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="0" ref="diskStore"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="sizeOfPolicy"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="transactionManagerLookup"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="cacheManagerEventListenerFactory"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="managementRESTService"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerProviderFactory"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerListenerFactory"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="terracottaConfig"/>
                <xs:element maxOccurs= "1" minOccurs="0" ref="defaultCache"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cache"/>
            </xs:sequence>
            <xs:attribute name="name" use="optional"/>
            <xs:attribute default="true" name="updateCheck" type="xs:boolean" use="optional"/>
            <xs:attribute default="autodetect" name="monitoring" type="monitoringType" use="optional"/>
            <xs:attribute default="true" name="dynamicConfig" type="xs:boolean" use="optional"/>
            <xs:attribute default="15" name="defaultTransactionTimeoutInSeconds" type="xs:integer" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnit" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnit" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="managementRESTService">
        <xs:complexType>
            <xs:attribute name="enabled" type="xs:boolean" use="optional"/>
            <xs:attribute name="bind" use="optional"/>
            <xs:attribute name="securityServiceLocation" use="optional"/>
            <xs:attribute name="securityServiceTimeout" use="optional" type="xs:integer"/>
            <xs:attribute name="sslEnabled" use="optional" type="xs:boolean"/>
            <xs:attribute name="needClientAuth" use="optional" type="xs:boolean"/>
            <xs:attribute name="sampleHistorySize" use="optional" type="xs:integer"/>
            <xs:attribute name="sampleIntervalSeconds" use="optional" type="xs:integer"/>
            <xs:attribute name="sampleSearchIntervalSeconds" use="optional" type="xs:integer"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="diskStore">
        <xs:complexType>
            <xs:attribute name="path" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="transactionManagerLookup">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerEventListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerPeerProviderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerPeerListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="terracottaConfig">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="0" name="tc-config">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute default="localhost:9510" name="url" use="optional"/>
            <xs:attribute name="rejoin" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="wanEnabledTSA" type="xs:boolean" use="optional" default="false"/>
        </xs:complexType>
    </xs:element>
    <!-- add clone support for addition of cacheExceptionHandler. Important! -->
    <xs:element name="defaultCache">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="pinning"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="sizeOfPolicy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="persistence"/>
            </xs:sequence>
            <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
            <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
            <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
            <xs:attribute name="eternal" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxElementsInMemory" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxEntriesLocalHeap" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
            <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
            <xs:attribute name="overflowToDisk" type="xs:boolean" use="optional"/>
            <xs:attribute name="timeToIdleSeconds" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="timeToLiveSeconds" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxElementsOnDisk" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxEntriesLocalDisk" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/>
            <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/>
            <xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cache">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="pinning"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="searchable"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="sizeOfPolicy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="persistence"/>
            </xs:sequence>
            <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
            <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
            <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
            <xs:attribute name="eternal" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxElementsInMemory" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxEntriesLocalHeap" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
            <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
            <xs:attribute name="name" type="xs:string" use="required"/>
            <xs:attribute name="overflowToDisk" type="xs:boolean" use="optional"/>
            <xs:attribute name="timeToIdleSeconds" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="timeToLiveSeconds" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxElementsOnDisk" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxEntriesLocalDisk" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="maxEntriesInCache" type="xs:nonNegativeInteger" use="optional"/>
            <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off" />
            <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="logging" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/>
            <xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnitOrPercentage" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheEventListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
            <xs:attribute name="listenFor" use="optional" type="notificationScope" default="all"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="bootstrapCacheLoaderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheExtensionFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheExceptionHandlerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheLoaderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheDecoratorFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="searchAttribute">
        <xs:complexType>
        	<xs:attribute name="name" use="required" type="xs:string" />
        	<xs:attribute name="expression" type="xs:string" />
        	<xs:attribute name="class" type="xs:string" />
        	<xs:attribute name="type" type="xs:string" use="optional"/>
        	<xs:attribute name="properties" use="optional" />
        	<xs:attribute name="propertySeparator" use="optional" />
        </xs:complexType>
    </xs:element>

    <xs:element name="searchable">
      <xs:complexType>
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="searchAttribute"/>
        </xs:sequence>
        <xs:attribute name="keys" use="optional" type="xs:boolean" default="true"/>
        <xs:attribute name="values" use="optional" type="xs:boolean" default="true"/>
        <xs:attribute name="allowDynamicIndexing" use="optional" type="xs:boolean" default="false"/>
      </xs:complexType>
    </xs:element>

    <xs:element name="pinning">
        <xs:complexType>
            <xs:attribute name="store" use="required" type="pinningStoreType"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="terracotta">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="nonstop"/>
            </xs:sequence>
            <xs:attribute name="clustered" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="coherentReads" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="localKeyCache" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="localKeyCacheSize" use="optional" type="xs:positiveInteger" default="300000"/>
            <xs:attribute name="orphanEviction" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="orphanEvictionPeriod" use="optional" type="xs:positiveInteger" default="4"/>
            <xs:attribute name="copyOnRead" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="coherent" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="consistency" use="optional" type="consistencyType" default="eventual"/>
            <xs:attribute name="synchronousWrites" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="concurrency" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="localCacheEnabled" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="compressionEnabled" use="optional" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="consistencyType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="strong" />
            <xs:enumeration value="eventual" />
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="nonstop">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="timeoutBehavior"/>
            </xs:sequence>
            <xs:attribute name="enabled" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="immediateTimeout" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="timeoutMillis" use="optional" type="xs:positiveInteger" default="30000"/>
            <xs:attribute name="searchTimeoutMillis" use="optional" type="xs:positiveInteger" default="30000"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="timeoutBehavior">
        <xs:complexType>
            <xs:attribute name="type" use="optional" type="timeoutBehaviorType" default="exception"/>
            <xs:attribute name="properties" use="optional" default=""/>
            <xs:attribute name="propertySeparator" use="optional" default=","/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="timeoutBehaviorType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="noop" />
            <xs:enumeration value="exception" />
            <xs:enumeration value="localReads" />
            <xs:enumeration value="localReadsAndExceptionOnWrite" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="monitoringType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="autodetect"/>
            <xs:enumeration value="on"/>
            <xs:enumeration value="off"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="pinningStoreType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="localMemory" />
            <xs:enumeration value="inCache" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="terracottaCacheValueType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="serialization" />
            <xs:enumeration value="identity" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="transactionalMode">
        <xs:restriction base="xs:string">
            <xs:enumeration value="off"/>
            <xs:enumeration value="xa_strict"/>
            <xs:enumeration value="xa"/>
            <xs:enumeration value="local"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="cacheWriter">
        <xs:complexType>
            <xs:sequence >
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriterFactory"/>
            </xs:sequence>
            <xs:attribute name="writeMode" use="optional" type="writeModeType" default="write-through"/>
            <xs:attribute name="notifyListenersOnException" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="minWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="maxWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="rateLimitPerSecond" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="writeCoalescing" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="writeBatching" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="writeBatchSize" use="optional" type="xs:positiveInteger" default="1"/>
            <xs:attribute name="retryAttempts" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="retryAttemptDelaySeconds" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="writeBehindConcurrency" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="writeBehindMaxQueueSize" use="optional" type="xs:nonNegativeInteger" default="0"/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="writeModeType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="write-through" />
            <xs:enumeration value="write-behind" />
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="cacheWriterFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="copyStrategy">
        <xs:complexType>
            <xs:attribute name="class" use="required" type="xs:string" />
        </xs:complexType>
    </xs:element>

    <xs:element name="elementValueComparator">
        <xs:complexType>
            <xs:attribute name="class" use="required" type="xs:string" />
        </xs:complexType>
    </xs:element>

    <xs:element name="sizeOfPolicy">
        <xs:complexType>
            <xs:attribute name="maxDepth" use="required" type="xs:integer" />
            <xs:attribute name="maxDepthExceededBehavior" use="optional" default="continue" type="maxDepthExceededBehavior" />
        </xs:complexType>
    </xs:element>

	<xs:element name="persistence">
	    <xs:complexType>
            <xs:attribute name="strategy" use="required" type="persistenceStrategy"/>
            <xs:attribute name="synchronousWrites" use="optional" default="false" type="xs:boolean"/>
	    </xs:complexType>
	</xs:element>
	
	<xs:simpleType name="persistenceStrategy">
	    <xs:restriction base="xs:string">
	        <xs:enumeration value="localTempSwap"/>
	        <xs:enumeration value="localRestartable"/>
	        <xs:enumeration value="none"/>
	        <xs:enumeration value="distributed"/>
	    </xs:restriction>
	</xs:simpleType>
	
    <xs:simpleType name="maxDepthExceededBehavior">
        <xs:restriction base="xs:string">
            <xs:enumeration value="continue"/>
            <xs:enumeration value="abort"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="notificationScope">
        <xs:restriction base="xs:string">
            <xs:enumeration value="local"/>
            <xs:enumeration value="remote"/>
            <xs:enumeration value="all"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="memoryUnit">
        <xs:restriction base="xs:token">
            <xs:pattern value="[0-9]+[bBkKmMgG]?"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="memoryUnitOrPercentage">
        <xs:restriction base="xs:token">
            <xs:pattern value="([0-9]+[bBkKmMgG]?|100%|[0-9]{1,2}%)"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

4)编写过滤器:

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;

/**
 * 页面缓存过滤器
 * 页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!
 * 其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。
 * SimplePageCachingFilter适用于缓存整个页面的情况,如果只需要缓存某一个片段,如使用jsp:include包含的部分,请使用SimplePageFragmentCachingFilter。
 */
public class PageEhCacheFilter extends SimplePageCachingFilter{


    private static String[] cacheURLArray;

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, 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) {
            	System.out.println(cacheURL+"  "+requestURL);
                if (requestURL.contains(cacheURL.trim())) {//判断当前请求是否是要缓存的url
                	containCacheURLFlag = true;
                    break;
                }
            }
        }

        if (containCacheURLFlag) {//当前请求是要缓存的url
            String queryString = request.getQueryString();
            if (StringUtils.isNotEmpty(queryString)) {//当前请求含有采用问号传过来的参数
            	queryString = "?" + queryString;
            	System.out.println("当前请求被缓存:" + requestURL + queryString);
            }else{
            	System.out.println("当前请求被缓存:" + 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方法来实现。
     */
    @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;
    }
}

5)编写jsp界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Date,java.text.SimpleDateFormat"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>首页</title>
	</head>
	
	<body>
		<div style="text-align:center;margin-top:360px;">
			<font style="color:green;font-weight:bold;font-size: 18px"><%=new SimpleDateFormat("yyyy-MM-dd hh:MM:ss").format(new Date())%></font><br><br>
			<font style="color:red;font-weight:bold;font-size: 27px">每次刷新页面,如果时间是变动的,则说明该页面没有被缓存或缓存已经过期,否则则说明该页面已经被缓存。</font>
		</div>
	</body>
</html>

以上是关于Ehcache 页面缓存的主要内容,如果未能解决你的问题,请参考以下文章

Ehcache 整合Spring 使用页面对象缓存

Ehcache 整合Spring 使用页面对象缓存

Ehcache 整合Spring 使用页面对象缓存

Ehcache 页面缓存

ehcache 页面整体缓存和局部缓存

我们究竟什么时候可以使用Ehcache缓存(转)