|
Recipe 3.2: Caching static and semi-static data in JSP
Problem
Processing static or semi-static data in JSP on every request is redundant and inefficient.
Background
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?
Recipe
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.
Listing 5.4 shows the usage of caching in JSP subsections using oscache.
| Listing5.4
CacheClient.jsp
<%@ page import="com.cookbook.servlet.helper.*"
%>
<%@ taglib uri="oscache" prefix="cache"
%> #1
<cache:cache time="7200"> #2
<%= getItems() %>
</cache:cache>
<%!
public String getItems(){ #3
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();
}
%>
(annotation)<#1
Declare oscache tag library>
(annotation)<#2 Cache the processed items for 7200 seconds
(2 hours) and refresh>
(annotation)<#3 Process items using helper class>
|
| |
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.
|