Mar*_*ula 23
使用ResourceFilterFactory可以轻松使用Jersey - 您可以创建附加到方法的任何自定义注释来设置缓存控制设置.ResourceFilterFactories被调用每个已发现资源的方法,当应用程序初始化 - 在你ResourceFilterFactory您可以检查方法有你@CacheControlHeader注释(或任何你想将它命名) - 如果不是,简单地返回响应滤波器,增加了"无缓存"指示响应,否则应使用注释中的设置.以下是如何执行此操作的示例:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注释可能如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CacheControlHeader {
String value();
}
Run Code Online (Sandbox Code Playgroud)
通过将以下init参数添加到web.xml中Jersey servlet的定义,可以在应用程序中注册ResourceFilterFactory:
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>package.name.CacheFilterFactory</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 14
根据@ martin-matula的解决方案,我创建了两个Cache注释.一个@NoCache
不用缓存,一个@CacheMaxAge
用于特定缓存.在CacheMaxAge
有两个参数,这样你就不必自己计算秒:
@GET
@CacheMaxAge(time = 10, unit = TimeUnit.MINUTES)
@Path("/awesome")
public String returnSomethingAwesome() {
...
}
Run Code Online (Sandbox Code Playgroud)
ResourceFilter现在有这个create方法,默认情况下不会干扰(所以其他缓存机制继续工作):
@Override
public List<ResourceFilter> create(AbstractMethod am) {
if (am.isAnnotationPresent(CacheMaxAge.class)) {
CacheMaxAge maxAge = am.getAnnotation(CacheMaxAge.class);
return newCacheFilter("max-age: " + maxAge.unit().toSeconds(maxAge.time()));
} else if (am.isAnnotationPresent(NoCache.class)) {
return newCacheFilter("no-cache");
} else {
return Collections.emptyList();
}
}
private List<ResourceFilter> newCacheFilter(String content) {
return Collections
.<ResourceFilter> singletonList(new CacheResponseFilter(content));
}
Run Code Online (Sandbox Code Playgroud)
您可以在我的博文中看到完整的解决方案.
谢谢马丁的解决方案!
@ martin-matula的解决方案不适用于JAX-RS 2.0/Jersey 2.x,因为ResourceFilterFactory和ResourceFilter已被删除.该解决方案可以如下适用于JAX-RS 2.0.
注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CacheControlHeader {
String value();
}
Run Code Online (Sandbox Code Playgroud)
DynamicFeature:
@Provider
public class CacheFilterFactory implements DynamicFeature {
private static final CacheResponseFilter NO_CACHE_FILTER =
new CacheResponseFilter("no-cache");
@Override
public void configure(ResourceInfo resourceInfo,
FeatureContext featureContext) {
CacheControlHeader cch = resourceInfo.getResourceMethod()
.getAnnotation(CacheControlHeader.class);
if (cch == null) {
featureContext.register(NO_CACHE_FILTER);
} else {
featureContext.register(new CacheResponseFilter(cch.value()));
}
}
private static class CacheResponseFilter implements ContainerResponseFilter {
private final String headerValue;
CacheResponseFilter(String headerValue) {
this.headerValue = headerValue;
}
@Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext) {
// attache Cache Control header to each response
// based on the annotation value
containerResponseContext
.getHeaders()
.putSingle(HttpHeaders.CACHE_CONTROL, headerValue);
}
}
}
Run Code Online (Sandbox Code Playgroud)
CacheFilterFactory需要在Jersey注册.我是通过Dropwizard来做的 - 使用environment.jersey().register() - 但是在独立系统上我理解这可以通过让Jersey通过在web.xml中定义以下内容来扫描类的@Provider注释来完成:
<servlet>
<servlet-name>my.package.MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under my.package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)
有关注册组件的更多信息,请参阅此文章.
归档时间: |
|
查看次数: |
21352 次 |
最近记录: |