Thursday 24 September 2015

Jersey 2 : Cache control using RESTfull Web Service

In this post, I am going to exaplan the usage of HTTP header ‘Cache-Control’.

Caching is the important aspect of any web application success. Web caching is a technique of storing static documents, images, style sheets etc.,

Types of web caching
There are two types of web caching.
a.   Browser caching
b.   Proxy caching

Browser caching
Browser maintains temporary storage area on your disk space to cache data. When you visit a website, browser stores static pages, images, style sheets, js scripts etc., of this website. When you revisit the same website, browser checks which content is updated, and download only updated content. This reduces the network bandwidth usage between client and server.

Proxy caching
Most organizations use proxy server to serve internet. A proxy server sits between your browser and real server. Whatever the url you request, it goes to proxy server, proxy server process your request on behalf of you and send you the response. Proxy cache is a function of proxy server, which cache the responses in server harddisk. So next time if any user ask for same page, it delivers from its cache.

Cache-Control header
HTTP 1.1 specification introduces cache-control header. ‘cache-control’ header specifies set of directives which define who can cache, how long data can be cached etc..


cache-response-directive  
Directive
Description
public
Response may be cached by any cache.
private
Only client can cache the data, no proxy, no intermittent users can cache the data.
no-cache
Response should not be cached. If cached, data should be validated with server
no-store
Do not store information
max-age
Specifies how long cached data is valid
s-maxage
If a response includes an s-maxage directive, then for a shared cache (but not for a private cache), the maximum age specified by this directive overrides the maximum age specified by either the max-age directive or the Expires header.

I am not covering all the directives here, please go through following link for more information.

Following are some of the examples,
a. cache-control: no-cache, no-store

b. Cache-Control: private, no-transform, max-age=30

How Jersey support cache-control header?
The JAX-RS specification provides javax.ws.rs.core.CacheControl class to represent the Cache-Control header. While sending a response, you can set cache-control header.

@GET
@Produces(MediaType.TEXT_PLAIN)
public Response message() {
         CacheControl cc = new CacheControl();
         cc.setMaxAge(30);
         cc.setPrivate(true);

         return Response.ok("Hello").cacheControl(cc).build();
}

Above snippet sets maximum cache age to 30 seconds, specifies response shouldn’t stored on disk and cached only by client.

Following step-by-step procedure demonstrate complete working application using eclipse.

Step 1: Create new dynamic web project ‘jersey_cache’.
File -> New -> Dynamic web project

Give project name as ‘jersey_cache’, press Next.

Select the check box ‘Generate web.xml deployment descriptor’.


Press Finish.

Step 2: Convert this project to maven project.
Right click on the project -> Configure -> Convert To Maven project.

Total project structure looks like below.


Step 3: Update web.xml like below.

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>jersey_cache</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
  <servlet-name>Jersey REST Service</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>jersey.config.server.provider.packages</param-name>
   <param-value>com.self_learn</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>Jersey REST Service</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>

</web-app>

Step 4: Update pom.xml for maven dependencies.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>jersey_cache</groupId>
 <artifactId>jersey_cache</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <build>
  <sourceDirectory>src</sourceDirectory>
  <plugins>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
     <source>1.8</source>
     <target>1.8</target>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
     <warSourceDirectory>WebContent</warSourceDirectory>
     <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
   </plugin>
  </plugins>
 </build>

 <dependencies>
  <dependency>
   <groupId>org.glassfish.jersey.containers</groupId>
   <artifactId>jersey-container-servlet-core</artifactId>
   <version>2.21</version>
  </dependency>
 </dependencies>
</project>


Step 5: Create simple Resource, HelloWorld.java.

package com.self_learn.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Response;

@Path("hello")
public class HelloWorld {
 @GET
 @Produces
 public Response message() {
  long time = System.currentTimeMillis();

  CacheControl cc = new CacheControl();
  cc.setMaxAge(30);
  cc.setPrivate(true);

  String message = "System time in millis " + time;

  return Response.ok(message).cacheControl(cc).build();
 }

}

How to test the application.
Run the application on server, and hit following url on server.

You will get system time in milli seconds, try to refresh the window, you will get same output until next 30 seconds (since I set maximum cache age to 30 seconds cc.setMaxAge(30)).

If you had Advanced Rest client plugin of chrome browser, you can observe Cache-Control header.






Prevoius                                                 Next                                                 Home

No comments:

Post a Comment