0

WHAT I WANT

I'm working on a maven-jetty-plugin that uses jersey to map resources. How can I cache the version number for 5 hours so that I don't have to GET it every time the page loads?

MY CODE

Here is the html code that will contain the version number once it is loaded:

...

<footer>
  <hr/>
  VERSION: <span id="version-container">...Loading...</span>
</footer>

Here is the web.xml with the servlet mapping to 'localhost:8080/rest/':

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.resources</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

Here is the java code to handle a GET at 'localhost:8080/rest/version':

/* ... package & imports omitted ... */

@Path("/")
public class RootResource {

    @GET
    @Path("/version")
    @Produces(MediaType.APPLICATION_JSON)
    public String versionAsJson(){
        return String.format("{ \"version\": \"%s\"}", "v.01");
    }
}

Here is the javascript code to load the version after the page loads (using jQuery):

$(document).ready(function() {
    $.get("http://localhost:8080/rest/version",
        function(response){
            $("#version-container").html(response.version);
        },
        "json"
    ).error(function(){
        $("#version-container").html("[FAILED TO GET VERSION]");
    });
}
Community
  • 1
  • 1
NoBrainer
  • 5,853
  • 1
  • 27
  • 27

1 Answers1

0

The Guava library has very nice cache support:

@Path("/")
public class Service {

  protected LoadingCache<String, String> cache = CacheBuilder.newBuilder()
      .expireAfterWrite(5L, TimeUnit.HOURS).maximumSize(1L)
      .build(new CacheLoader<String, String>() {
        @Override
        public String load(String key) throws Exception {
          return String.format("{ \"version\": \"%s\"}", "v.01");
        }
      });

  @GET
  @Path("/version")
  @Produces(MediaType.APPLICATION_JSON)
  public String run() throws ExecutionException {
    return cache.get("version");
  }

}
condit
  • 10,852
  • 2
  • 41
  • 60
  • Just tried it out and it's working correctly for me. The code in the load method should only run if it's been more than five hours since the last call to the service. Is that the behavior you're looking for? And can you provide more details about what you're seeing? – condit Jun 26 '12 at 21:32
  • I got your solution to work, but I don't think it solves my problem. I want to cache the response so that I don't have to call GET every time. Your solution still calls GET every time. I feel that the solution may need to be javascript/html level...? – NoBrainer Jun 27 '12 at 13:42
  • I got a few suggestions (when told to look into caching) to modify the 'etag', 'cache-control', and 'last-modified' in the html meta tags. I spent hours googling and trying things I found but to no avail. – NoBrainer Jun 27 '12 at 15:09
  • Are you trying to avoid using the network at all? You could store the service call result in [local storage](http://diveintohtml5.info/storage.html) with a timestamp and then the client could make the decision during a reload to use the stored value or issue another request to the service. – condit Jun 27 '12 at 15:59
  • After going over requirements, I now realize that I need to have this working on IE7... So, would you happen to know a good way to do this that would work on IE7? – NoBrainer Jun 27 '12 at 19:14
  • I haven't used it but you could try something like [jStorage](http://www.jstorage.info/) which abstracts browser storage for you and works on older versions of IE. – condit Jun 27 '12 at 19:33
  • You've definitely provided me with the tools I need to solve my problem. Thanks! – NoBrainer Jun 28 '12 at 20:44