2012-10-29 14 views
1

是否有可能为每个资源定义缓存控制级别?每个资源的泽西缓存控制

是否有一些注释可以放在每个Resource类的顶部,以便以自定义的方式指定缓存控件?

+0

如果你能使用泽西2.0:http://jalg.net/2012/09/declarative-cache-control-with-jax- rs-2-0/ – Friso

+0

这看起来很酷。你确定它只适用于2.0吗? – mfirry

+0

不是,但文章是关于展示新功能,特别是新的Filter API。还没有尝试过。 – Friso

回答

0

为了解决这个问题,我最终定义了一个@Cache方面。有几个需要注意的地方,我跑进:

  • 缓存的方法需要返回一个Response对象(PO​​JO的不是),这样的方面可以修改标题。

  • 如果您想使用ETags,那么包含方法(或方法参数本身)的类需要公开@Request,以便方面可以检查传入标记。

  • 确保您的方法参数与您的方法名称结合在一起实际上会创建唯一的键。这里的另一个问题是响应类型。客户端可以发出两个具有相同参数但响应类型不同的请求。

  • 您可以轻松地将选项添加到该方面,以便按照每个方法控制max-age和其他参数。

这里是我的invoke方法:

@Override 
public Object invoke(MethodInvocation invocation) throws Throwable { 
    if (Response.class != invocation.getMethod().getReturnType()) { 
    logger.warning(String.format("%s is @Cachable but does not return a Response object", invocation.getMethod())); 
    return invocation.proceed(); 
    } 

    Optional<Request> request = getRequest(invocation); 
    if (!request.isPresent()) { 
    logger.warning(String.format("%s is @Cachable but does not declare a public Request field named \"request\"", invocation.getMethod())); 
    return invocation.proceed(); 
    } 

    Object response = super.invoke(invocation); 
    EntityTag responseTag = JaxRsUtil.getEntityTag(response); 

    Response.ResponseBuilder builder = request.get().evaluatePreconditions(responseTag); 
    if (null != builder) { 
    logger.finer("Found matching etag: " + responseTag); 
    return builder.build(); 
    } 
    CacheControl cc = new CacheControl(); 
    cc.setMaxAge(maxAge); 
    builder = Response.fromResponse((Response)response).tag(responseTag).cacheControl(cc); 
    return builder.build(); 
} 
+0

看起来像很多工作:(将看看,如果这就是我们想要做的。非常感谢 – mfirry

+1

这是一个更容易,非AOP方式使用'ContainerResponseFilter':https://github.com/algermissen/cache-control - 装饰者。 – condit