The dynamic cache service of WebSphere Application Server V5 allows you to cache the output of servlets and JSP files.
The caching service works within the application server process. It is invoked prior to a service() method call of a servlet. The service can either execute the service() method and save the output in the cache or directly serve cached content and avoid a call to the service() method.
In this document we will show how to configure basic servlet caching in a web application.
DEVELOP A TEST APPLICATION
We will develop a simple product information display application. The price of the product will be random. Before we enable cache, we will see the price changing everytime we refresh the browser. After we configure caching, the price will change only after we change the value of the productId URL parameter.
Create the Web Application
Create a web application called TestWeb under an enterprise application called Test. Do not create any EJB project.
Create the Servlet
Create a servlet called ProductDisplay in the package com.webage.servlet.
In the doGet() method of the ProductDisplay servlet add code as follows:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String productId = req.getParameter("productId"); if (productId == null || productId.length() == 0) { throw new ServletException("Invalid productId parameter"); } //We generate semi-dynamic values instead of database lookup. String description = "Product description for ID: " + productId; double price = java.lang.Math.random() * 100.00; String strPrice = java.text.NumberFormat.getCurrencyInstance().format(price); req.setAttribute("description", description); req.setAttribute("price", strPrice); req.getRequestDispatcher("product.jsp").forward(req, resp); }
Create a JSP file called product.jsp and set it’s HTML content as follows:
<BODY> <H1>Product Details</H1> <p>Description: <%=request.getAttribute("description")%></p> <p>Price: <%=request.getAttribute("price")%></p> </BODY>
Run the servlet in a WAS V5 server and notice how the price changes as you refresh the browser.
Stop the server.
CONFIGURE CACHE
CONFIGURE SERVLET CACHING
Create a file called cachespec.xml in the WSAD_ROOTruntimesbase_v5properties directory. Set the content to:
<?xml version="1.0"?> <!DOCTYPE cache SYSTEM "cachespec.dtd"> <!--Sample--> <cache> <cache-entry> <class>servlet</class> <name>/TestWeb/ProductDisplay</name> <cache-id> <component id="productId" type="parameter"> <required>true</required> </component> </cache-id> </cache-entry> </cache>
Here, we make the productId URL parameter a part of the cache key. In other words, for every unique productId value a new cache will be created. You can make a composite key by supplying more <component> entries under a <cache-id> element.
CONFIGURE THE WEB CONTAINER
Open the properties screen of the server. Click on the Configuration tab and enable admin client for the server. Start the server.
Right click on the server and select Run administrative console. After you log in, expand Servers->Application Servers. Click on server1. Click on on the Dynamic cache service. Make sure that the Enable service at startup is checked (this is enabled by default). Next, click on the Web container service. Check Enable servlet caching. Click OK and then save the changes.
Log out of admin console and restart the server.
TEST
Run the servlet from the browser again. Notice, how the display will remain the same, until you supply a different productId parameter value.
WEBSPHERE DEPLOYMENT
Export the test project as an EAR file and install it in a stand alone WebSphere instance. Configure the web container of the application server as described above. Copy the cachespec.xml file in the WebSphereAppServerproperties folder.
MOVING CACHE TO THE HTTP SERVER
By default, the cached content is stored in the application server (web container). That means when a request for a cached URL is made, the request flows through the web server all the way to the web container. This continues to put minimal load on the web server. At least a thread in the web container gets occupied while it fetches content from the cache. You can propagate the cached content to the web server to eliminate any involvement of the web container. This type of caching is called Edge Side Include (ESI) caching.
When ESI cache is enabled, the web container uses special HTTP reply header to instruct the web server plugin that the reply content should be cached. ESI cache is always cached in memory of each web server process. If you are running IBM HTTP Server 1.3.x, the total memory requirement can be very high. It is strongly recommended that you move to IBM HTTP Server v6 where you can run a small number of child processes.
Before you enable ESI cache, make sure that dynamic caching has been configured following the steps mentioned above. Next, in the cachespec.xml file, set the EdgeCacheable property to true for a cached URL.
<?xml version="1.0"?> <!DOCTYPE cache SYSTEM "cachespec.dtd"> <!--Sample--> <cache> <cache-entry> <class>servlet</class> <name>/TestWeb/ProductDisplay</name> <property name="EdgeCacheable">true</property> <cache-id> <component id="productId" type="parameter"> <required>true</required> </component> </cache-id> </cache-entry> </cache>
Next, configure ESI cache at the web server plugin level. In WebSphere 5.1, ESI caching is enabled by default. The size of the cache is set to 1MB. Open plugin-cfg.xml. Under the <Config> tag, you can add the following two properties to enable ESI cache and set the cache size.
<Config ...> <Property Name="ESIEnable" Value="true"/> <Property Name="ESIMaxCacheSize" Value="1024"/>
CONCLUSION
WebSphere makes it easy to cache dynamic content. You can start with simple caching scenarios like shown here. Later, you can implement cache time out and session based caching.