当前位置: 首页 > 面试题库 >

我正在尝试使用Java的HttpURLConnection进行“有条件获取”,但是我从未获得304状态代码

孟财
2023-03-14
问题内容

这是我的代码:

    final HttpURLConnection conn = (HttpURLConnection) sourceURL.openConnection();
    if (cachedPage != null) {
        if (cachedPage.eTag != null) {
            conn.setRequestProperty("If-None-Match", cachedPage.eTag);
        }
        conn.setIfModifiedSince(cachedPage.pageLastModified);
    }

    conn.connect();

    if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {

        newCachedPage.eTag = conn.getHeaderField("ETag");
        newCachedPage.pageLastModified = conn.getHeaderFieldDate("Last-Modified", 0);

    } else if (conn.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
        // Never reaches here
    }

我似乎从未得到HTTP_NOT_MODIFIED响应代码,甚至连连几次击中同一台服务器-页面绝对没有变化。另外,conn.getHeaderField(“
ETag”)似乎总是响应null,有时conn.getHeaderFieldDate(“ Last-
Modified”,0)返回0。我已经在各种Web服务器上进行了尝试。

谁能告诉我我在做什么错?


问题答案:

你们都依赖于服务器配置。

如果获得Expires响应头,则仅意味着您无需在指定的到期时间之前请求任何内容。如果获得Last- Modified响应头,则意味着您应该可以使用If-Modified- Since它来进行测试。如果获得ETag响应头,则意味着您应该可以使用If-None-Match它来进行测试。

让我们以http://cdn3.sstatic.net/stackoverflow/img/favicon.ico为例(Stackoverflow的favicon图像):

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();
System.out.println(connection.getHeaderFields());

这给出:

{null = [HTTP / 1.1 200 OK],ETag = [“ 9d9bd8b1165cb1:0”],日期=
[2011年8月17日星期三,格林尼治标准时间],Content-Length = [1150],最后修改时间=
[周三,2010年10月6日02:53:46 GMT],内容类型= [图像/ x-图标],连接= [保持活动],接受范围= [字节],服务器=
[nginx / 0.8.36] ,X-Cache = [HIT],Cache-Control = [max-age = 604800]}

现在,使用If-Modified- Since与相同的值进行Last- Modified

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();
connection.setRequestProperty("If-Modified-Since", "Wed, 06 Oct 2010 02:53:46 GMT");
System.out.println(connection.getHeaderFields());

这给出了预期的304:

{null = [HTTP / 1.1 304未修改],ETag = [“ 9d9bd8b1165cb1:0”],日期=
[星期三,2011年8月17日17:57:42 GMT],上次修改时间= [星期三,2010年10月6日02: 53:46 GMT],连接=
[keep-alive],服务器= [nginx / 0.8.36],X-Cache = [HIT],Cache-Control = [max-age
= 604800]}

现在,使用If-None- Match与相同的值进行ETag

URLConnection connection = new URL("http://cdn3.sstatic.net/stackoverflow/img/favicon.ico").openConnection();
connection.setRequestProperty("If-None-Match", "9d9bd8b1165cb1:0");
System.out.println(connection.getHeaderFields());

出乎意料地 给了200:

{null = [HTTP / 1.1 200 OK],ETag = [“ 9d9bd8b1165cb1:0”],日期=
[2011年8月17日星期三,格林尼治标准时间],Content-Length = [1150],最后修改时间=
[周三,2010年10月6日02:53:46 GMT],内容类型= [图像/ x-图标],连接= [保持有效],接受范围= [字节],服务器=
[nginx / 0.8.36] ,X-Cache = [HIT],Cache-Control = [max-age = 604800]}

更令人惊讶的是,当两个标头都设置为随机垃圾值时ETag,服务器仍给出304。这表明http://cdn3.sstatic.netIf- None- Match后面的服务器完全忽略了。那可能是一个(代理)配置问题,或者是完全有意识地完成的(不是出于明显的原因恕我直言)。



 类似资料: