Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityTag - Value, Caching, Comparison - how to in Jersey

Tags:

rest

http

jersey

at the moment im trying to enable caching for my jersey restful service.

So there occure some questions.

  1. Whats the the value of the entityTag? Can it just be a unique generated random string?

  2. When I make a post request from my client to the server, I get back the response with the entity tag. Question: how to cache this and how do I know which cached entityTag I have to send for the next get request?

  3. On server side I get the sended entityTag. How do I compare this with the ressource? Because i didnt attach the entityTag to the ressource.

  4. Its just about comparing entityTags. So when do I need the last-modified header value?

Sorry, would be nice to get an example for server and client side. I cant find anything for this issue. How to send entityTags in request, how to compare them on server side and what abouts last-modified.

like image 476
user1460679 Avatar asked Jun 21 '12 12:06

user1460679


1 Answers

ETags provide a mechanism for client cache to validate if it's cached content is still up-to-date. Regarding your questions:

  1. Up to the server to decide - it has to uniquely identify the version of the resource at a given point of time (can be a revision number of the resource, or CRC32 hash of the resource representation, or anything else that can be used to determine if the resource has changed or not)
  2. Jersey does not provide any support for client-side caching at the moment. You can create your own cache by implementing a ClientFilter that intercepts a client request, looks into it's internal HashMap (for example) that maps URI, media type and request method to an cached response. Takes the ETag from that cached response and attaches it to the client request. When server responds, the filter checks if the server responded with 304 (Not Modified) status code, if so, the filter returns the previously cached response to the client, if not, it caches the response returned from the server and returns that to the client.
  3. By sending the entity tag in the request the client basically says: "I have a version of the entity corresponding the this entity tag - is the entity still the same, or has it changed? If it has changed, send me the new version of the entity along with the tag!". If server did not send any entity tag in the initial response, client does not know the tag corresponding to the cached entity and so it can't send a tag in it's request. Server knows the meaning of the tag - for the client the tag value is opaque.
  4. You can either one of them or both.

On the server side, Jersey provides support for evaluating ETags and generating a response. E.g. your resource method can look like this:

@GET
public Response doGet() {
    EntityTag et = yourMethodForCalculatingEntityTagForThisResource();

    // the following method call will result in Jersey checking the headers of the
    // incoming request, comparing them with the entity tag generated for
    // the current version of the resource generates "304 Not Modified" response
    // if the same. Otherwise returns null.
    ResponseBuilder rb = request.evaluatePreconditions(new EntityTag("1"));
    if (rb != null) {
        // Jersey generated 304 response - return it
        return rb.build();
    }
    // return the current version of the resource with the corresponding tag
    return Response.ok(getCurrentVersion(), "text/plain").tag(et).build();
}

Same kind of support is provided for last-modified header and also both etag and last-modified.

This wikipedia article provides a nice overview of ETags: http://en.wikipedia.org/wiki/HTTP_ETag

like image 105
Martin Matula Avatar answered Oct 12 '22 08:10

Martin Matula