ETag 为客户端缓存提供了一种机制,以验证其缓存的内容是否仍然是最新的。关于你的问题:
- 由服务器决定 - 它必须在给定时间点唯一标识资源的版本(可以是资源的修订号,或资源表示的 CRC32 散列,或任何其他可用于确定资源是否已更改)
- Jersey 目前不提供对客户端缓存的任何支持。您可以通过实现拦截客户端请求的 ClientFilter 创建自己的缓存,查看将 URI、媒体类型和请求方法映射到缓存响应的内部 HashMap(例如)。从该缓存响应中获取 ETag 并将其附加到客户端请求。当服务器响应时,过滤器检查服务器是否响应了 304(未修改)状态码,如果是,则过滤器将之前缓存的响应返回给客户端,如果没有,则缓存服务器返回的响应并将其返回给客户端客户。
- 通过在请求中发送实体标签,客户端基本上说:“我有一个对应于这个实体标签的实体版本 - 实体仍然是一样的,还是已经改变了?如果它已经改变,给我发送新版本的实体和标签!”。如果服务器在初始响应中没有发送任何实体标签,则客户端不知道缓存实体对应的标签,因此它无法在其请求中发送标签。服务器知道标签的含义——对于客户端,标签值是不透明的。
- 您可以选择其中之一或两者兼而有之。
在服务器端,Jersey 支持评估 ETag 和生成响应。例如,您的资源方法可能如下所示:
@GET
public Response doGet() {
EntityTag et = yourMethodForCalculatingEntityTagForThisResource();
// the following method call will result in Jersey checking the headers of the
// incoming request, comparing them with the entity tag generated for
// the current version of the resource generates "304 Not Modified" response
// if the same. Otherwise returns null.
ResponseBuilder rb = request.evaluatePreconditions(new EntityTag("1"));
if (rb != null) {
// Jersey generated 304 response - return it
return rb.build();
}
// return the current version of the resource with the corresponding tag
return Response.ok(getCurrentVersion(), "text/plain").tag(et).build();
}
为 last-modified 标头以及 etag 和 last-modified 提供了相同类型的支持。
这篇维基百科文章很好地概述了 ETag:http ://en.wikipedia.org/wiki/HTTP_ETag