Cache-Control with Jersey 2.0
Inspired by this StackOverflow question, I decided to write a Cache-Control Annotation for Jersey 2.0 (actually 2.2 but that doesn't matter anyways since it's JAX-RS 2.0)
First of, the Annotation which will provide binding the resources to the actual cache header insertion:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;
@NameBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
String value() default "public, must-revalidate";
}
Next, you need the actual implementation of the cache header insertion - this will look for a @CacheControl
annotation and add the provided string, if found, to the response header:
import java.io.IOException;
import java.lang.annotation.Annotation;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
@Provider
@CacheControl
public class CacheControlFilter
implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext pRequestContext, ContainerResponseContext pResponseContext)
throws IOException {
for (Annotation a : pResponseContext.getEntityAnnotations()) {
if (a.annotationType() == CacheControl.class) {
String value = ((CacheControl) a).value();
pResponseContext.getHeaders().putSingle(HttpHeaders.CACHE_CONTROL, value);
break;
}
}
}
}
Now you can use the @CacheControl
header in your resources:
@Path("/api")
public class SomeResource {
@GET
@Path("/not-cacheable")
@CacheControl("no-cache")
public Respone handleNoneCacheableRequest() {
return Response.ok().build();
}
}
Caveats so far:
- If you declare
@CacheControl
on your resource class, the CacheControlFilter will not match it and does therefore not add a header - this is becausepResponseContext.getEntityAnnotations()
will only match Annotations declared directly on the method but not on its class declarations or other ancestors. Unfortunately I did not come up with a solution for this yet.
Written by Remo Koch
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Java
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#