users@jersey.java.net

[Jersey] Creating Etags via ContainerResponseFilter

From: Jonathan Hodges <hodgesz_at_gmail.com>
Date: Mon, 30 Apr 2012 19:06:17 -0600

Hi,

I have been having some difficulty implementing etags in a
ContainerResponseFilter and was hoping I can get some assistance. So far I
have implemented the following filter method.


public ContainerResponse filter(ContainerRequest containerRequest,
ContainerResponse containerResponse) {
        logger.debug("request URI: "+containerRequest.getAbsolutePath());

        if (isEligibleForEtag(containerRequest, containerResponse)) {

                Object entity = containerResponse.getEntity();
                Object originalEntity =
containerResponse.getOriginalEntity();
                java.lang.reflect.Type entityType =
containerResponse.getEntityType();

                if (entity != null) {

                        EntityTag etag = generateETag(originalEntity);
                        Response.ResponseBuilder responseBuilder =
request.evaluatePreconditions(etag);
                        if (responseBuilder != null) {
                            logger.debug("entity has not changed so
returning unmodified response code");

containerResponse.setResponse(responseBuilder.build());
                        } else {
                            responseBuilder =
containerResponse.getResponse().fromResponse(containerResponse.getResponse());

containerResponse.setResponse(responseBuilder.tag(etag).build());
                        }
                }
        }

        return containerResponse;
}


The first problem is that the filter is called before the serialization of
the entity so there isn't a good way to get the bytes required to calculate
a strong etag. I could create a ServletFilter to manage this instead, but
wanted to confirm I wasn't missing something in the Jersey framework as
that is the preferred approach.

The next problem is with setting the etag in the ConatainerResponse. I
didn't see a straightforward way to do this, but I certainly could have
missed something. As you can see in the example above I made a shallow
copy of the ContainterResponse Response object to create a
Response.ResponseBuilder to add the etag. Is there a better way?

Thanks in advance for your assistance as we really enjoy Jersey.

-Jonathan