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