Blogs Blogs


Custom Caching Framework based on Portlet Filters




  1. ehCache
    (Download: )

  2. Liferay 6.0.3

  3. Filter Source code (Download: )


Introduced as part of JSR-286, portlet filters dynamically intercept requests from and responses back to the portlet container. Just like Servlet filters, portlet filters can be leveraged for caching responses to improve the performance.

The following article presents how combining portlet filters and Terracotta’s in-memory ehCahe can boost the portlet performance, in turn reducing the back-end traffic and providing blazing performance to deliver content. ehCache provides convenient REST based APIs to populate and invalidate cache that applications surfaced as portlets could leverage.


Ehcache is an open source, standards-based cache used to boost performance, offload the database and simplify scalability. Ehcache is robust, proven and full-featured and this has made it the most widely- used Java-based cache.

It can scale from in-process with one or more nodes through to a mixed in-process/out-of-process configuration with terabyte-sized caches. For applications needing a coherent distributed cache, Ehcache uses the open source Terracotta Sever Array.

Ehcache is actively developed, maintained and supported as a professional open source project by Terracotta, Inc. and is available under an Apache 2 license.

Request/Response flow:

  1. End-User requests for a page containing portlets

  2. Cache Filter intercepts the request, initializes the filter on the first request, extracts and

    instantiates the necessary classes based on the initialization parameters defined in portlet.xml


  3. Filter checks the cache against a user defined cache key implementation and for a cache-miss

    sends the request to the portlet along with a wrapped response, retrieves the mark-up, and,

  4. Caches the content before sending the response to the next filter in-line on the way back to the

    portlet container

    All subsequent requests from the portlet container to the portlet are served from the cache, until an external event happens that invalidates the cache or if cache expires.

ehCache Installation:

ehCache Configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi=""

xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true" >

<diskStore path=""/> <defaultCache

maxElementsInMemory="0" eternal="false" timeToIdleSeconds="1200" timeToLiveSeconds="1200">



This cache contains a maximum in memory of 10000 elements, and will expire an element if it is idle for more than 5 minutes and lives for more than 10 minutes.

If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever is defined on your system. On a standard Linux system this will be /tmp"

<cache name="Acme_WDFCache" maxElementsInMemory="10000"

maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU"


Filter Classes:

[jboss@daffy /opt/app/liferay/liferay-portal-5.2-ee-sp3/tomcat- 6.0.18/webapps/WDF_UCM/WEB-INF/classes/com/schoolspecialty/wdf/filter/portlet]$ls -ltr total 20

-rw-rw-r-- 1 jboss jboss 936 Jul 21 16:22 CachedContent.class
-rw-rw-r-- 1 jboss jboss 2353 Jul 21 16:22 CachedRenderResponseWrapper.class -rw-rw-r-- 1 jboss jboss 7559 Aug 6 14:25 PortletCacheFilter.class -rw-rw-r-- 1 jboss jboss 2578 Aug 6 16:14 CachedOutputStream.class

[jboss@daffy /opt/app/liferay/liferay-portal-5.2-ee-sp3/tomcat- 6.0.18/webapps/WDF_UCM/WEB-INF/classes/com/schoolspecialty/wdf/cache]$ls -ltr total 16
-rw-rw-r-- 1 jboss jboss 1872 Jul 21 16:20 SSIPortletsCacheKey.class -rw-rw-r-- 1 jboss jboss 2474 Jul 21 16:20 EHCacheUtil.class
-rw-rw-r-- 1 jboss jboss 493 Jul 21 16:20 CacheUtil.class
-rw-rw-r-- 1 jboss jboss 372 Jul 21 16:20 CacheKeyIntf.class

CacheKeyIntf<T> defines a single method getKey that returns a client implemented key of type T Portlet Mapping File:


<filter-name>CacheFilter</filter-name> <filter-class>com.acme.filter.portlet.PortletCacheFilter</filter-class> <lifecycle>RENDER_PHASE</lifecycle>

<init-param> <name>CACHE_ALGORITHM</name> <value> x.x.x.EHCacheUtil</value>



<value>Acme_WDFCache</value> </init-param>

<init-param> <name>CACHE_KEY</name>

<value>x.x.x.SSIPortletsCacheKey </value> </init-param>

</filter> <filter-mapping>


<portlet-name>1</portlet-name> </filter-mapping>

Response Times:

1) Response is actually created for a UCM Portlet and returned (not cached): 22 ms avg 2) Response is returned from cache: 2 ms avg

Trackback URL:

Add Comment
It should be JSR 168 specifications instead of JSR 268. JSR 268 is for smart card IO API.
Posted on 3/24/15 4:54 PM.