Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey: Default Cache Control to no-cache

Tags:

While writing a RESTful web service, I am encountering issues if I enable any sort of caching on my client (currently a .NET thick client). By default Jersey is not sending any sort of cache control header, so the client is caching most pages automatically (which seems to be valid behaviour).

I would like to have Jersey by default send a cache control of "no-cache", and then in particular responses override the cache control.

Is there any way to do this with Jersey?

I've found that RESTeasy has the ability to use the @NoCache annotation to specify the setting for the whole class, but I've not found anything similar with Jersey.

like image 914
Pete Avatar asked Jun 07 '12 14:06

Pete


People also ask

What is set cache-control as no-cache?

The directive CACHE-CONTROL:NO-CACHE indicates cached information should not be used and instead requests should be forwarded to the origin server. This directive has the same semantics as the PRAGMA:NO-CACHE.

How to set cache-control header in Java?

Add an Expires or a Cache-Control header in JSP HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse. setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 httpResponse. setHeader("Pragma", "no-cache"); // HTTP 1.0 httpResponse.

What is cache-control No-store?

Cache-Control: No-Store The no-store directive means browsers aren't allowed to cache a response and must pull it from the server each time it's requested. This setting is usually used for sensitive data, such as personal banking details.

Is cache-control required?

Cache-control is an important way by which developers can dictate how resources will be cached when a user browses the internet. Without cache-control, the browser caching and the resulting experience for the user will be sub-optimal.


1 Answers

This is easy with Jersey by using a ResourceFilterFactory - you can create any custom annotation you attach to your methods to set cache control settings. ResourceFilterFactories get called for each discovered resource method when the application initializes - in your ResourceFilterFactory you can check if the method has your @CacheControlHeader annotation (or whatever you want to call it) - if not, simply return response filter that adds "no-cache" directive to the response, otherwise it should use the settings from the annotation. Here is an example of how to do that:

public class CacheFilterFactory implements ResourceFilterFactory {     private static final List<ResourceFilter> NO_CACHE_FILTER = Collections.<ResourceFilter>singletonList(new CacheResponseFilter("no-cache"));      @Override     public List<ResourceFilter> create(AbstractMethod am) {         CacheControlHeader cch = am.getAnnotation(CacheControlHeader.class);         if (cch == null) {             return NO_CACHE_FILTER;         } else {             return Collections.<ResourceFilter>singletonList(new CacheResponseFilter(cch.value()));         }     }      private static class CacheResponseFilter implements ResourceFilter, ContainerResponseFilter {         private final String headerValue;          CacheResponseFilter(String headerValue) {             this.headerValue = headerValue;         }          @Override         public ContainerRequestFilter getRequestFilter() {             return null;         }          @Override         public ContainerResponseFilter getResponseFilter() {             return this;         }          @Override         public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {             // attache Cache Control header to each response based on the annotation value             response.getHttpHeaders().putSingle(HttpHeaders.CACHE_CONTROL, headerValue);             return response;         }     } } 

The annotation can look like this:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CacheControlHeader {     String value(); } 

The ResourceFilterFactory can be registered in your application by adding the following init param to the definition of Jersey servlet in web.xml:

<init-param>     <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>     <param-value>package.name.CacheFilterFactory</param-value> </init-param> 
like image 182
Martin Matula Avatar answered Oct 11 '22 12:10

Martin Matula