Oracle iPlanet Web Server 7.0.9 Developer's Guide to Java Web Applications

Caching Servlet Results

Web Server can cache the results of invoking a servlet, a JSP page, or any URL pattern to make subsequent invocations of the same servlet, JSP page, or URL pattern faster. The Web Server caches the request results for a specific amount of time. In this way, if another data call occurs, the Web Server can return the cached data instead of performing the operation again. For example, if your servlet returns a stock quote that updates every 5 minutes, you set the cache to expire after 300 seconds.

If caching is enabled, Web Server can cache the results produced by the servlet javax.servlet.RequestDispatcher.include() or javax.servlet.RequestDispatcher.forward(). In Sun ONE Web Server releases, the result generated by a resource for which caching was enabled was never cached if that resource was the target of a javax.servlet.RequestDispatcher.include() or javax.servlet.RequestDispatcher.forward(). This result cached only if the resource was the target of the initial request.

<sun-web-app>
<cache enable="true">
		<cache-mapping>
				<servlet-name>TestServlet</servlet-name>
				<dispatcher>REQUEST</dispatcher>
				<dispatcher>FORWARD</dispatcher>
		</cahce-mapping>
		</cache>
	  </sun-web-app>

Whether to cache results and how to cache them depends on the data involved. For example, you do not need to cache the results of a quiz submission because the input to the servlet is different each time. However, you could cache a high-level report showing demographic data taken from quiz results that is updated once an hour.

You can define how a Web Server web application handles response caching by editing specific fields in the sun-web.xml file. In this way, you can create programmatically standard servlets that still take advantage of this feature.

For more information about JSP caching, see JSP Cache Tags.

Features of Caching

Web Server has the following web application response caching capabilities:

Default Cache Configuration

If you enable caching but do not provide any special configuration for a servlet or JSP page, the default cache configuration is as follows:

CacheHelper Interface

The CacheHelper interface includes the following information:

package com.sun.appserv.web.cache;
import java.util.Map
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/** CacheHelper interface is an user-extensible interface to customize:
 * a) the key generation b) whether to cache the response.
 */
public interface CacheHelper {
// name of request attributes
   public static final String ATTR_CACHE_MAPPED_SERVLET_NAME =
                           "com.sun.appserv.web.cachedServletName";
   public static final String ATTR_CACHE_MAPPED_URL_PATTERN =
                           "com.sun.appserv.web.cachedURLPattern";
public static final int TIMEOUT_VALUE_NOT_SET = -2;
/** initialize the helper
    * @param context the web application context this helper belongs to
    * @exception Exception if a startup error occurs
    */
   public void init(ServletContext context, Map props) throws Exception;
/** getCacheKey: generate the key to be used to cache this request
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns the generated key for this requested cacheable resource.
    */
   public String getCacheKey(HttpServletRequest request);
/** isCacheable: is the response to given request cacheable?
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns <code>true</code> if the response could be cached. or
    * <code>false</code> if the results of this request must not be cached.
    */
   public boolean isCacheable(HttpServletRequest request);
/** isRefreshNeeded: is the response to given request to be refreshed?
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns <code>true</code> if the response needs to be refreshed.
    * or return <code>false</code> if the results of this request
    * dont need to be refreshed.
    */
   public boolean isRefreshNeeded(HttpServletRequest request);
/** get timeout for the cached response.
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns the timeout in seconds for the cached response; a return
    * value of -1 means the response never expires and a value of -2 indicates
    * helper cannot determine the timeout (container assigns default timeout)
   */
public int getTimeout(HttpServletRequest request);
/**
    * Stop the helper from active use
    * @exception Exception if an error occurs
    */
   public void destroy() throws Exception;
}

Caching Example

The following example cache element in the sun-web.xml file:

<cache max-capacity="8192" timeout="60">
   <cache-helper name="myHelper" class-name="MyCacheHelper"/>
   <cache-mapping>
      <servlet-name>myservlet</servlet name>
      <timeout name="timefield">120</timeout>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
   </cache-mapping>
   <cache-mapping>
      <url-pattern> /catalog/* </url-pattern>
      <!-- cache the best selling category; cache the responses to
        -- this resource only when the given parameters exist. Cache
        -- only when the catalog parameter has qliliesq or qrosesq
        -- but no other catalog varieties:
        -- /orchard/catalogbest&category=lilies
        -- /orchard/catalogbest&category=roses
        -- but not the result of
        -- /orchard/catalog?best&category=wild
      -->
      <constraint-field name=best scope=request.parameter/>
      <constraint-field name=category scope=request.parameter>
        <value> roses </value>
        <value> lilies </value>
      </constraint-field>
      <!-- Specify that a particular field is of given range but the
        -- field does not need to be present in all the requests -->
      <constraint-field name=SKUnum scope=request.parameter>
        <value match-expr=qin-range> 1000 - 2000 </value>
      </constraint-field>
      <!-- cache when the category matches with any value other than
        -- a specific value -->
      <constraint-field name="category" scope="request.parameter>
        <value match-expr="equals" cache-on-match-failure="true">bogus</value>
      </constraint-field>
   </cache-mapping>
   <cache-mapping>
      <servlet-name> InfoServlet </servlet name>
      <cache-helper-ref>myHelper</cache-helper-ref>
   </cache-mapping>
</cache>

For more information about the sun-web.xml caching settings, see Caching Elements.

CacheKeyGenerator Interface

The built-in default CacheHelper implementation enables web applications to customize the key generation. An application component in a servlet or JSP can set up a custom CacheKeyGenerator implementation as an attribute in the ServletContext.

The name of the context attribute is configurable as the value of the cacheKeyGeneratorAttrName property in the default-helper element of the sun-web.xml deployment descriptor. For more information, see default-helper.

The CacheKeyGenerator interface contains the following information:

package com.sun.appserv.web.cache;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/** CacheKeyGenerator: a helper interface to generate the key that
 * is used to cache this request.
 *
 * Name of the ServletContext attribute implementing the
 * CacheKeyGenerator is configurable via a property of the
 * default-helper in sun-web.xml:
 * <default-helper>
 * <property
 * name="cacheKeyGeneratorAttrName"
 * value="com.acme.web.MyCacheKeyGenerator" />
 * </default-helper>
 *
 * Caching engine looks up the specified attribute in the servlet
 * context; the result of the lookup must be an implementation of the
 * CacheKeyGenerator interface.
 */
public interface CacheKeyGenerator {
/** getCacheKey: generate the key to be used to cache the
    * response.
    * @param context the web application context
    * @param request incoming <code>HttpServletRequest</code>
    * @returns key string used to access the cache entry.
    * if the return value is null, a default key is used.
    */
   public String getCacheKey(ServletContext context,
                           HttpServletRequest request);
}