J2EE cache filter

January 2nd, 2008 by Samuel Santos Leave a reply »

In my current web project I was having some performance issues, I needed a tool that allowed me to do some testing so I can see what’s wrong and what I can do better so my application perform faster.

My search lead me to High Performance Web Sites and YSlow, a very good talk by Steve Souders the Chief Performance Yahoo! at Yahoo!

YSlow is an easy-for-use plugin that allows you to inspect any web page just clicking a button.

YSlow analyzes web pages and tells you why they’re slow based on the rules for high performance web sites. YSlow is a Firefox add-on integrated with the popular Firebug web development tool. YSlow gives you:

  • Performance report card
  • HTTP/HTML summary
  • List of components in the page
  • Tools including JSLint

A good way to reduce the number of Http Connections required to load a web page is to store images and other resources in the browser cache.

Expires is a HTTP header that allows you to define when a resource (image, css, javascript, …) will need to be reloaded. It is a String representation of a Date in the format EEE, dd MMM yyyy HH:mm:ss z.
Cache-Control response headers give Web publishers more control over their content and address the limitations of Expires.

To correctly produce these headers I implemented a Java cache filter.
Using the cache filter is very simple. Grab it here and configure your web.xml, here’s an example:

<filter>
    <filter-name>imagesCache</filter-name>
    <filter-class>com.samaxes.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>privacy</param-name>
        <param-value>public</param-value>
    </init-param>
    <init-param>
        <param-name>expirationTime</param-name>
        <param-value>2592000</param-value><!-- 30 days -->
    </init-param>
</filter>

<filter>
    <filter-name>cssCache</filter-name>
    <filter-class>com.samaxes.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>privacy</param-name>
        <param-value>public</param-value>
    </init-param>
    <init-param>
        <param-name>expirationTime</param-name>
        <param-value>604800</param-value><!-- 7 days -->
    </init-param>
</filter>

<filter>
    <filter-name>javascriptCache</filter-name>
    <filter-class>com.samaxes.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>privacy</param-name>
        <param-value>private</param-value>
    </init-param>
    <init-param>
        <param-name>expirationTime</param-name>
        <param-value>172801</param-value><!-- 48 hours + 1 second -->
    </init-param>
</filter>

<filter-mapping>
    <filter-name>imagesCache</filter-name>
    <url-pattern>*.png</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>imagesCache</filter-name>
    <url-pattern>*.jpg</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>imagesCache</filter-name>
    <url-pattern>*.gif</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>cssCache</filter-name>
    <url-pattern>*.css</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>javascriptCache</filter-name>
    <url-pattern>*.js</url-pattern>
</filter-mapping>

Note: YSlow far future Expires header magical number is 172801 seconds (48 hours + 1 second).

Related Posts

Advertisement

9 comments

  1. Jay says:

    Very cool! I was looking for this exact thing just now, and your site was already covered by DZone and on the first page of Google results!

  2. Marty says:

    Is the java file for cache filter available?

  3. The link above was pointing to the wrong file.
    It’s fixed now.
    Thanks

  4. javier says:

    thanks for share this =)

  5. Gael Marziou says:

    Thanks for sharing your code.
    Any reason why you used response.setHeader() with your own date conversion method rather than using response.setDateHeader()?

  6. I’ve had some trouble in the past due to this problematic code:

    response.setDateHeader("Expires", System.currentTimeMillis() + (CACHE_DURATION * 1000));

    CACHE_DURATION * 1000 is an integer operation causing an overflow if CACHE_DURATION is set to be > MAX_INT/1000 seconds (approx. 25 days) which is less than the cache duration I use for images.

    Changing CACHE_DURATION to long or forcing a long operation fixes the problem:

    response.setDateHeader("Expires", System.currentTimeMillis() + CACHE_DURATION * 1000L);

    I will soon release a 1.0.3 version with this modification.
    Thanks for making me remember.

  7. karthik says:

    com.samaxes.cachefilter.presentation.CacheFilter java file available. I’m facing the same requriement here to ..!!! could you please share the file

Leave a Reply