Thursday, August 30, 2007

Caching static and semi-static data in JSP

A JSP is a combination of different sections. For example, the basic sections that a JSP contains are header, footer, navigation and body sections. These sections are generally independent of each other and most of these sections are either static or semi-static. For example, product categories in navigation bar do not change frequently. When you call a JSP, it process all data (static, semi-static and dynamic content) on every request but what we actually require to process is just the dynamic content.

So how can we avoid unnecessary static or semi-static data processing in JSP on every user request?

The recipe for this problem is to identify and cache static and semi-static sections in JSP. Cache should be refreshed at certain times depending up on data refreshing policy. If the data is fully static, you don't have to refresh it but it is a good practice to refresh after every day or week to make sure that any changes are reflected in JSP. A typical example of fully static data section is footer section in your JSP. If the data is semi-static, you should refresh the cache often depending upon its state change policy. An example for semi-static data sections in JSP is header or navigation sections. And some of the body sections also may be semi-static. You can identify and cache them accordingly to improve performance.

we have used free and well-implemented caching code oscache from opensymphony.com in this sample. You can see information on this at www.opensymphony.com/oscache. The below code shows the usage of caching in JSP subsections using oscache.

Code:

<%@ page import="com.cookbook.servlet.helper.*" %>
<%@ taglib uri="oscache" prefix="cache" %>
<cache:cache time="7200">
<%= getItems() %>
<cache:cache>
<%! public String getItems(){
ItemsHelper helper = new ItemsHelper();
List list = helper.getAllItems();
StringBuffer body = new StringBuffer();
if(list != null && list.size()>0){
ListIterator iter = list.listIterator();
body.append("<TABLE border=\"1\"><TBODY>");
while (iter.hasNext()) {
Item item = (Item) iter.next();
body.append("<TR>");
body.append("<TD>");
body.append(item.getName());
body.append("</TD>");
body.append("<TD>");
body.append(item.getDesc());
body.append("</TD>");
body.append("</TR>");
}
body.append("</TBODY></TABLE>");
}
return body.toString();
}
%>

Discussion:

You can cache any section of your JSP as shown in the above code. You can also give the location of cache store as application or session scope parameter in the oscache tag. The default is application scope. You should be careful when you use session scope in a clustered environment where the session data could be stored as persistent sessions depending upon configuration. There will be overhead involved in persistent sessions if the session data is huge.

In order to utilize oscache, all you need to do is just download the zip file from opensymphony.com/oscache, unzip it and place oscache.jar in /web-inf/lib directory, place oscache.properties and taglib.tld files in web-inf directory and configure web.xml file for this tag library as follows.

<taglib>
<taglib-uri>oscache</taglib-uri>
<taglib-location>/WEB-INF/oscache.tld</taglib-location>
</taglib>

You can also configure other caching properties in oscache such as cache capacity and type of algorithm in oscache.properties file.

No comments: