有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何有效地检查图片库网站的更改?

我目前正在开发一个同步服务,可以从exchange服务器获取所有用户配置文件图片。 为了跟踪变化,我决定对响应体进行MD5编码,并将其与数据库中的实体保持在一起,以便在路径上进一步比较,查看图片是否发生了变化。而实际图片本身保存在磁盘上

图片大小为504x504像素,因此重量约为27 kb。 由于我要获取字节码的散列值,即使图片匹配,我仍然必须下载27kb的数组,这几乎不会提高速度(除了我不需要在磁盘上替换它)。乘以大量用户,即使所有图片都匹配,这项工作也需要20分钟

有没有办法优化同步,以便在图片相同的情况下不下载响应正文? 以下是一些代码,可以帮助您更好地理解:

entity = restTemplate.getForEntity(
                Constant.EXCHANGE_URL_PREFIX + emailAddress + Constant.EXCHANGE_URL_SUFFIX, byte[].class);

这就是我所说的get请求

if (entity.hasBody()) {
 String hexHash = Hex.encodeHexString(MessageDigest.getInstance("MD5").digest(bytes));
 if (!listofHashes.contains(hexHash)) {
    picture.remove();
 } else picture.save();
}

总而言之:有没有一种方法可以使用restTemplate检测网页更改,而不下载整个页面?提前谢谢你

编辑:对ETag标题和@Cacheable注释的额外研究没有证明是成功的


共 (3) 个答案

  1. # 1 楼答案

    这实际上取决于与之通信的服务器的功能。如果该服务器不支持standard mechanisms^{}^{}等,如注释中所述)或发送任何其他自定义头,那么您别无选择,只能执行您描述的操作——计算客户端(在应用程序中)的响应体摘要

  2. # 2 楼答案

    您可以尝试使用HTTP GET,但只请求头

    然后,从回复中验证“内容长度”和“上次修改”(如果它们与您已存储的图像不匹配,则必须再次下载)

    例如,对维基百科中的一幅图像进行此操作,我得到了以下结果:

    content-length: 314402

    last-modified: Thu, 31 Oct 2013 14:45:43 GMT

    请注意,关于“内容长度”:

    The Content-Length entity-header field indicates the size of the entity-body, in decimal number of OCTETs, sent to the recipient or, in the case of the HEAD method, the size of the entity-body that would have been sent had the request been a GET. (see more here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)

    这是我使用的curl命令:

    $ curl -X HEAD -I "https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/            Lifeboat.17-31.underway.arp.jpg/1200px-Lifeboat.17-31.underway.arp.jpg"
    
    HTTP/2 200 
    date: Thu, 29 Jun 2017 08:30:29 GMT
    content-type: image/jpeg
    content-length: 314402
    x-object-meta-sha1base36: oboqyviefa9uqy9p7391dxgod784onh
    last-modified: Thu, 31 Oct 2013 14:45:43 GMT
    etag: 188492bd99a0032624df62205d156bb4
    x-timestamp: 1383230742.02258
    x-trans-id: tx73ff02723dc5476c92e0a-005953e448
    x-varnish: 894182014 897225224, 41759639 11075541, 415722130
    via: 1.1 varnish-v4, 1.1 varnish-v4, 1.1 varnish-v4
    accept-ranges: bytes
    age: 54876
    x-cache: cp1063 hit/1, cp3045 hit/72, cp3049 pass
    x-cache-status: hit
    strict-transport-security: max-age=31536000; includeSubDomains; preload
    x-analytics: https=1;nocookies=1
    x-client-ip: 82.181.132.52
    access-control-allow-origin: *
    access-control-expose-headers: Age, Date, Content-Length, Content-Range, X-Content-    Duration, X-Cache, X-Varnish
    timing-allow-origin: *
    
  3. # 3 楼答案

    条件GET

    如果您的服务器实现了standard of Http1.1,则可以使用以下对之一来实现:

    • 上次修改/如果自
    • ETag/如果没有匹配

    如果etag匹配或自上次获取日期以来未修改,服务器应返回304(未修改)

    示例:

    请求头:

    If-Modified-Since:Sat, 06 Aug 2016 05:22:27 GMT
    If-None-Match:"02c7fd69fa875302f71b714fa2787cc95fa88245"
    

    响应标题:

    Last-modified:Sat, 04 Apr 2015 09:05:44 GMT
    Etag: "02c7fd69fa875302f71b714fa2787cc95fa88245"
    

    结论

    • 实际上,你所做的应该由你的exchange服务器而不是客户端来完成,这就是304的目的
    • 最后一种修改方式会受到分布式系统中时间漂移的影响,而Etag则不会
    • 另一方面,Etag可能涉及文件系统的inode信息,因此移动文件也可能会影响Etag值

    Ref