5

目前我正在尝试为我的球衣宁静服务启用缓存。

所以出现了一些问题。

  1. entityTag 的值是多少?它可以只是一个唯一生成的随机字符串吗?

  2. 当我从客户端向服务器发出发布请求时,我会返回带有实体标签的响应。问题:如何缓存它以及我如何知道我必须为下一个获取请求发送哪个缓存的 entityTag?

  3. 在服务器端,我得到了发送的 entityTag。我如何将其与资源进行比较?因为我没有将 entityTag 附加到资源。

  4. 它只是关于比较实体标签。那么我什么时候需要最后修改的标头值呢?

抱歉,很高兴获得服务器和客户端的示例。我找不到任何关于这个问题的东西。如何在请求中发送 entityTags,如何在服务器端比较它们以及最后修改的内容。

4

1 回答 1

8

ETag 为客户端缓存提供了一种机制,以验证其缓存的内容是否仍然是最新的。关于你的问题:

  1. 由服务器决定 - 它必须在给定时间点唯一标识资源的版本(可以是资源的修订号,或资源表示的 CRC32 散列,或任何其他可用于确定资源是否已更改)
  2. Jersey 目前不提供对客户端缓存的任何支持。您可以通过实现拦截客户端请求的 ClientFilter 创建自己的缓存,查看将 URI、媒体类型和请求方法映射到缓存响应的内部 HashMap(例如)。从该缓存响应中获取 ETag 并将其附加到客户端请求。当服务器响应时,过滤器检查服务器是否响应了 304(未修改)状态码,如果是,则过滤器将之前缓存的响应返回给客户端,如果没有,则缓存服务器返回的响应并将其返回给客户端客户。
  3. 通过在请求中发送实体标签,客户端基本上说:“我有一个对应于这个实体标签的实体版本 - 实体仍然是一样的,还是已经改变了?如果它已经改变,给我发送新版本的实体和标签!”。如果服务器在初始响应中没有发送任何实体标签,则客户端不知道缓存实体对应的标签,因此它无法在其请求中发送标签。服务器知道标签的含义——对于客户端,标签值是不透明的。
  4. 您可以选择其中之一或两者兼而有之。

在服务器端,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

于 2012-06-22T08:54:23.323 回答