EntityTag - 价值,缓存,比较 - 如何在泽西岛

时间:2012-06-21 12:31:20

标签: http rest jersey

目前我正试图为我的平针织服务提供缓存服务。

所以出现了一些问题。

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

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

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

  4. 它只是比较entityTags。那么我什么时候需要最后修改的标头值?

  5. 很抱歉,很高兴为服务器端和客户端提供示例。我找不到这个问题。如何在请求中发送entityTags,如何在服务器端比较它们以及最后修改的内容。

1 个答案:

答案 0 :(得分:8)

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

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

    为最后修改的标题以及etag和last-modified提供了相同的支持。

    这篇维基百科文章提供了对ETag的一个很好的概述:http://en.wikipedia.org/wiki/HTTP_ETag