Friday, October 24, 2014

Caching Web Page content using ETag in Spring MVC

Most of the time we are talking about caching web pages to reduce the network traffic and network bandwidth in order to improve the user experience. But the concern is how many times we succeed on this technique after investing lots of effort on this to make it work.

There are couple of techniques available now a days to cache the web pages. In this post we will be discussing the easiest way to caching the page in an efficient way using Spring MVC framework.

Technical Background
An ETag(entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL. 

It can be considered to be the more sophisticated successor to the Last-Modified header. When a server returns a representation with an ETag header, the client can use this header in subsequent GETs, in an If-None-Match header. If the content has not changed, the server returns 304: Not Modified.

Implementation
Support for ETags is provided by the Spring servlet filter ShallowEtagHeaderFilter. It is declared under package org.springframework.web.filter. It is a plain Servlet Filter, and thus can be used in combination with any web framework. 
The ShallowEtagHeaderFilter filter creates so-called shallow ETags (as opposed to deep ETags, more about that later).The filter caches the content of the rendered JSP (or other content), generates an MD5 hash over that, and returns that as an ETag header in the response. 
The next time a client sends a request for the same resource, it uses that hash as the If-None-Match value. The filter detects this, renders the view again, and compares the two hashes. If they are equal, a 304 is returned. This filter will not save processing power, as the view is still rendered. The only thing it saves is bandwidth, as the rendered response is not sent back over the wire.

Example:










After that start the server and access the resource and observe the request/response readers. In the request you can see the If-None-Match header and in response ETag header. The value of both the headers are same.

















3 comments:

  1. After puting the filters in the web.xml i had tried hitting the service again and i got a 304. but i still get the response data. If i get a response data then what is the purpsoe of etag and 304 ?

    ReplyDelete
  2. If you got a 304 response code, the content is probably loaded from the browser cache. You should check your service invocation in order to really test if the content body is returned by the service itself, but I doubt it.

    ReplyDelete
  3. Filter that generates an ETag value based on the content on the response. This ETag is compared to the If-None-Match header of the request. If these headers are equal, the response content is not sent, but rather a 304 "Not Modified" status instead.
    Since the ETag is based on the response content, the response (e.g. a View) is still rendered. As such, this filter only saves bandwidth, not server performance.

    ReplyDelete