泽西岛:默认缓存控制为无缓存 [英] Jersey: Default Cache Control to no-cache
问题描述
在编写RESTful Web服务时,如果在客户端(当前是.NET胖客户端)上启用任何类型的缓存,就会遇到问题.默认情况下,Jersey不发送任何类型的缓存控制标头,因此客户端会自动缓存大多数页面(这似乎是有效的行为).
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).
我希望默认情况下,Jersey发送一个"no-cache"缓存控件,然后特别是响应将覆盖该缓存控件.
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?
我发现RESTeasy可以使用@NoCache批注指定整个类的设置,但是我找不到与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.
推荐答案
在Jersey中,使用ResourceFilterFactory很容易-您可以创建附加到方法的任何自定义注释来设置缓存控制设置.应用程序初始化时,将为每个发现的资源方法调用ResourceFilterFactories-在您的ResourceFilterFactory中,您可以检查该方法是否具有@CacheControlHeader批注(或任何您想调用的注解)-如果没有,只需返回添加"no-cache"的响应过滤器"作为指向响应的指令,否则应使用批注中的设置.这是如何执行此操作的示例:
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;
}
}
}
注释看起来像这样:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CacheControlHeader {
String value();
}
通过在web.xml中的Jersey servlet定义中添加以下初始化参数,可以在您的应用程序中注册ResourceFilterFactory:
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>
这篇关于泽西岛:默认缓存控制为无缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!