Dynamic fragment caching (also known as servlet caching) involves caching the request at the WebSphere Application Server layer. This type of caching is not as fast as pre-rendering, but it is faster than Web Content Management caching and, depending on your needs, can be more flexible.
Although servlet caching cannot cache personalized content, it can be used to selectively cache or not cache individual pages. Depending on the type of rendering that is used, servlet caching can be enabled to either cache the results of portlets or the Web Content Management servlet.
For the WCM local rendering portlet, please see the article on servlet caching. The Web Content Viewer (JSR 286) portlet is prepared to use portlet fragment caching to improve performance of Workplace Web Content Management sites. In order to prepare for such a setup, first enable servlet caching. Then enable portlet fragment caching.
Leveraging portlet fragment caching
There are several ways how the Web Content Viewer (JSR 286) portlet can leverage portlet fragment caching. Two aspects are important here. One is the generation of cache ids for the portlet, the other is the definition of a caching policy.
Cache id generation
With regards to cache id generation, there are three possibilities:
If you do not specify otherwise, the WebSphere Portal default cache id generator for JSR portlets will be used. In this case, all render parameters will be part of the cache id.
If you provide a cachespec.xml in the portlet war file you can customize cache id generation and specify exclusion of certain web content items from the cache. See
The render parameters WCM_CONTEXT and PUBLIC_CONTEXT for the Web Content Viewer (JSR 286) portlet control which web content item is actually rendered. In a cache-id element, those render parameters must be referred to by using the type "parameter-list". The render parameter PUBLIC_CONTEXT is used for broadcasting, WCM_CONTEXT otherwise. You can also filter on these render parameters using
, e.g.:
<component id="WCM_CONTEXT" type="parameter-list">
<required>false</required>
<not-value>/countries/world/europe/switzerland</not-value>
</component>
Please note that beside these two parameter the portlet also uses other render parameters i.e. the handle pagination links generated from page components in WCM. Instead of including all render parameters as components of the cache ID you can also use the following to include all parameters into the cache ID.
<component id="com.ibm.wsspi.portletcontainer.all_parameters" type="attribute">
<required>false</required>
</component>
Implement a custom idgenerator
For the sake of completeness, it should be mentioned that WebSphere Application Server provides an interface to extend cache id generation with custom code. However this is outside the scope of this article.
Caching policies
Caching policies for portlets may be defined on several levels. For the Web Content Viewer Portlet (JSR 286), two methods are of special interest:
-
configure cache scope and timeout globally for the portlet using WebSphere Portal Administration
-
configure cache scope and timeout for specific instances of the portlet using Edit Shared Settings mode
Examples
The following cachespec.xml may be used as a starting point for custom caching configurations. The portlet war file needs to be updated so that cachespec.xml is located in the WEB-INF folder. You must re-deploy the portlet after this has been done.
WebSphere Portal 6.1.5/7.0 running on WAS 7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">
<cache>
<cache-entry>
<class>portlet</class>
<name>Web Content Viewer (JSR 286)</name>
<property name="consume-subfragments">true</property>
<cache-id>
<component id="idLocale" type="locale"/>
<component id="idMode" type="portletMode">
<value>view</value>
</component>
<component id="idWindowId" type="portletWindowId"/>
<component id="idPWS" type="portletWindowState">
<not-value>minimized</not-value>
</component>
<component id="com.ibm.wsspi.portletcontainer.response_contenttype" type="attribute"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute">
<required>false</required>
</component>
<component id="javax.portlet.lifecycle_phase" type="attribute">
<value>RENDER_PHASE</value>
</component>
<component id="PUBLIC_CONTEXT" type="parameter-list">
<required>false</required>
</component>
<component id="WCM_CONTEXT" type="parameter-list">
<required>false</required>
</component>
<component id="PAGE_DESIGN" type="parameter-list">
<required>false</required>
</component>
<component id="WCM_QUERY" type="parameter-list">
<required>false</required>
</component>
<component id="pcid" type="parameter-list">
<required>false</required>
<value>NOTCACHED</value>
</component>
<component id="javax.portlet.render_part" type="attribute">
<value>RENDER_MARKUP</value>
</component>
</cache-id>
<dependency-id>action
<component id="depWindowId" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
</dependency-id>
<invalidation>action
<component id="invWindowId" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
<component id="javax.portlet.lifecycle_phase" type="attribute" ignore-value="true">
<value>ACTION_PHASE</value>
<value>EVENT_PHASE</value>
</component>
</invalidation>
</cache-entry>
</cache>
WebSphere Portal 6.1.5 running on WAS 6.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">
<cache>
<cache-entry>
<class>portlet</class>
<name>Web Content Viewer (JSR 286)</name>
<property name="consume-subfragments">true</property>
<cache-id>
<component id="idLocale" type="locale"/>
<component id="idMode" type="portletMode">
<value>view</value>
</component>
<component id="idWindowId" type="portletWindowId"/>
<component id="idPWS" type="portletWindowState">
<not-value>minimized</not-value>
</component>
<component id="com.ibm.wsspi.portletcontainer.response_contenttype" type="attribute"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute">
<required>false</required>
</component>
<component id="javax.portlet.lifecycle_phase" type="attribute">
<value>RENDER_PHASE</value>
</component>
<component id="PUBLIC_CONTEXT" type="parameter-list">
<required>false</required>
</component>
<component id="WCM_CONTEXT" type="parameter-list">
<required>false</required>
</component>
<component id="PAGE_DESIGN" type="parameter-list">
<required>false</required>
</component>
<component id="WCM_QUERY" type="parameter-list">
<required>false</required>
</component>
<component id="pcid" type="parameter-list">
<required>false</required>
<value>NOTCACHED</value>
</component>
</cache-id>
<dependency-id>action
<component id="depWindowId" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
</dependency-id>
<invalidation>action
<component id="invWindowId" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
<component id="javax.portlet.lifecycle_phase" type="attribute" ignore-value="true">
<value>ACTION_PHASE</value>
<value>EVENT_PHASE</value>
</component>
</invalidation>
</cache-entry>
</cache>
Cache Replication
In a clustered Portal environment with cache replication, the recommended setting for cache replication policy is NOT_SHARED, which is also the default setting if you omit it from the cachespec.xml. In case your WebSphere environment has a different default setting, here' how to add it to the cachespec.xml: create a new child element in the "cache" element:
<sharing-policy>not-shared</sharing-policy>
In some cases it is necessary to exclude non-serializable request attributes from being saved with the cache entry. Add the following as a child element to the "cache" element:
<property name="save-attributes">true
<exclude>javax.portlet.ccpp</exclude>
</property>