By cwebster on Jan 21, 2008
I am working on a project which has a fixed daily deployment schedule, Monday through Friday there is a 9:45 deployment. I wanted to take advantage of the known deployment schedule to incorporate Cache control directives when serving static resources. Currently, Glassfish is serving the static resources so I wrote a simple Filter which I applied to the static resource patterns. The filter is instantiated when the web module loads, so the next deployment serves as the appropriate caching period (the period will vary based on the day, the Friday deployment will be cached over the weekend).
Glassfish (as well as other servers like Apache) will set the Last Modified and ETag headers. These headers still require the client to issue an HTTP request for the resource; however, the server may respond with a 304 status code which indicates the content was not modified since the given date and etag (a mechanism for detecting change in the contents of the resource, like a hashcode). This is accomplished by the client sending the If-Modified-Since header along with the If-None-Match header to let the server know the date and "signature" of the file currently cached. The server will return a 304 if the response would return the same resource which saves the network transmission time for the resource.
This approach doesn't solve the problem where browsers generally only request two resources from the same domain in parallel, so if there are hundreds of resources on a page the overhead of determining whether the resource was current could impact the page load and hence the user experience. Instead I wanted to use the regular deployment cycle to reduce the number of requests required to determine whether resources are up to date.
The filter sets both the HTTP 1.0 Expires header as well as the HTTP 1.1 Cache Control Directive, to ensure both protocols are covered. If you are using apache to server static (or dynamic) resources you can find a good resource for setting up apache modules to do something similar on websiteoptimization.com. Glassfish has admin console capabilities for configuring caching which should be evaluated before doing everything in code.
If you want to give it a try in a web module, you will need to edit web.xml to add a filter and a filter mapping:
<url-pattern>/images/\*</url-pattern> <!-- these patterns should match cached resources -->
Add the filter class to the web module along with adjusting the appropriate timeout.