Configuring caching policies for portlets
Fragment caching for portlets requires that you define a cache policy in a cachespec.xml file, either within the portlet web application archives (WAR) file or globally. If no caching policy is defined and applicable to a particular portlet, that porlet is not cached.
WebSphere® Application Server caching policies provide a lot of flexibility for defining cache IDs and invalidation rules that match the specific requirements of individual portlets. The caching policies that you can define are not necessarily compliant with the caching behavior that is defined by the Java Portlet Specification. The following sections provide some recommendations on how you can exploit the features of cachespec.xml file, to define a caching policy that conforms to the specification.
Cache expiration
. Portlets define cache expiration
time in the <expiration-cache> element of the portlet.xml deployment
descriptor. If this element is not present, or has a value of zero,
the portlet is not cached. The cache expiration time for portlets
is only defined in the deployment descriptor; any cache timeout values
that are specified in a cachespec.xml file have no effect.
Caching scopes
. Portlets are defined in the <caching-scope>
element of the portlet.xml deployment descriptor, whether the portlet
content should be shared across all users or whether it contains user-specific
information and must be cached individually for each user. To maintain
this setting in your caching policy definition, include the com.ibm.wsspi.portletcontainer.user_cache_scope attribute
in your cache key, with the following cache key component:<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
This
attribute has the following values:- The value, public, in a portlet that defines public cache scope.
- The current logon user ID in a portlet that defines private cache scope.
- Null (anonymous) in a portlet that defines private cache scope if no user is logged on.
If you want to cache portlet content for anonymous access, even in a portlet that defines private cache scope, add <required>false</required> to the cache key component. This implies that all anonymous browser access will retrieve the same cache content.
Portlet lifecycle methods
. The Java Portlet Specification
defines the four lifecycle phases: action, event, render and resource
for running in a portlet. Only the render and resource phases produce
content; the action and event phases invoke portlet activity without
generating content and must not be cached. The lifecycle phase for
a portlet call is available in the javax.portlet.lifecycle_phase
request
attribute. Check for the correct lifecycle by including the following
cache key component:<component id="javax.portlet.lifecycle_phase" type="attribute">
<value>RENDER_PHASE</value>
</component>
This cache key component
only caches render requests to the portlet. Cache additional resource
requests by adding the RESOURCE_PHASE. In many cases, the best approach
is to define a separate <cache-id>
element
for resource requests. The resource ID is available in the com.ibm.wsspi.portletcontainer.resource_id request
attribute for caching key generation in resource requests.Request parameters
. Portlets can typically display
multiple views. Render parameters distinguish which view displays.
Each combination of parameters addresses a different view of the portlet.
All views need to be cached separately; therefore, the full request
parameter map should normally be included in the cache key. The com.ibm.wsspi.portletcontainer.all_parameters attribute
provides a unique value for the content of the full request parameter
map that can be used with the following cache key component:<component id="com.ibm.wsspi.portletcontainer.all_parameters" type="attribute">
<required>false</required>
</component>
If you write a cache policy for a specific
portlet, and you know exactly which views of the portlet are addressed
by which request parameters, it is usually more efficient to use specific <parameter>
elements
in the cache key to cache only the most important views of the portlet.Other cache key components
. Depending on your
usage scenario, you will need to include other information in your
cache key, if the returned content depends on it (for example, the
portlet mode and window state, or the request locale in a multi-language
portal). In a multi-device portal that supports different markup types,
the returned content type should also be part of the cache key. The
content type for a portlet is available in the com.ibm.wsspi.portletcontainer.response_contenttype request
attribute.
Cache invalidation
. The Java Portlet Specification
states that action and event requests to a portlet must invalidate
all currently cached content. The portlet caching definitions usually
allow for caching multiple views of a portlet at the same time. To
invalidate all of them, use the dependency ID mechanism of cachespec.xml.
<dependency-id>action
<component id="" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
</dependency-id>
ignore-value
attribute on the condition
part. The lifecycle attribute must not be part of the returned invalidation
ID, because that invalidation ID must match exactly with the dependency
ID previously specified.<invalidation>action
<component id="" 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>
Sample cachespec.xml file
<?xml version="1.0" ?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">
<cache>
<cache-entry>
<class>portlet</class>
<name>MyPortlet</name>
<property name="consume-subfragments">true</property>
<cache-id>
<component id="" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
<component id="" type="portletWindowState">
<!-- minimized portlets are not cached -->
<not-value>minimized</not-value>
</component>
<component id="" type="portletMode"/>
<component id="" type="locale"/>
<component id="com.ibm.wsspi.portletcontainer.response_contenttype" type="attribute"/>
<component id="com.ibm.wsspi.portletcontainer.all_parameters" type="attribute">
<required>false</required>
</component>
<component id="javax.portlet.lifecycle_phase" type="attribute">
<value>RENDER_PHASE</value>
</component>
</cache-id>
<dependency-id>action
<component id="" type="portletWindowId"/>
<component id="com.ibm.wsspi.portletcontainer.user_cache_scope" type="attribute"/>
</dependency-id>
<invalidation>action
<component id="" 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>