|
|
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
|