5

これが私のコードです:

    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 サーバーに対してこれを試しました。

誰が私が間違っているのか教えてもらえますか?

4

2 に答える 2

17

あなたはすべてサーバー構成に依存しています。

応答ヘッダーを取得した場合はExpires、指定された有効期限まで何も要求する必要がないことを意味します。応答ヘッダーを取得した場合は、それを使用してテストLast-Modifiedできるはずです。If-Modified-Since応答ヘッダーを取得した場合は、それを使用してテストETagできるはずです。If-None-Match

例としてhttp://cdn3.sstatic.net/stackoverflow/img/favicon.icoを見てみましょう(Stackoverflow のファビコン画像):

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"]、Date=[Wed, 17 Aug 2011 17:57:07 GMT]、Content-Length=[1150]、Last-Modified=[水、2010 年 10 月 6 日 02:53:46 GMT]、Content-Type=[image/x-icon]、Connection=[keep-alive]、Accept-Ranges=[bytes]、Server=[nginx/0.8.36] 、X-キャッシュ=[ヒット]、キャッシュ制御=[最大年齢=604800]}

If-Modified-Since次に、と同じ値でaを実行し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 Not Modified], ETag=["9d9bd8b1165cb1:0"], Date=[Wed, 17 Aug 2011 17:57:42 GMT], Last-Modified=[Wed, 06 Oct 2010 02: 53:46 GMT]、Connection=[keep-alive]、Server=[nginx/0.8.36]、X-Cache=[HIT]、Cache-Control=[max-age=604800]}

If-None-Match次に、と同じ値でaを実行し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"]、Date=[2011 年 8 月 17 日水曜日 18:01:42 GMT]、Content-Length=[1150]、Last-Modified=[水、2010 年 10 月 6 日 02:53:46 GMT]、Content-Type=[image/x-icon]、Connection=[keep-alive]、Accept-Ranges=[bytes]、Server=[nginx/0.8.36] 、X-キャッシュ=[ヒット]、キャッシュ制御=[最大年齢=604800]}

さらに驚くべきことに、両方のヘッダーにランダムなガベージ値が として設定されている場合ETagでも、サーバーは 304 を返します。これは、http://cdn3.sstatic.netIf-None-Matchの背後にあるサーバーが を完全に無視していることを示しています。それは(プロキシ)構成の問題であるか、完全に意識して行われている可能性があります(明らかな理由ではありません)。

于 2011-08-17T18:19:04.250 に答える
-4

または短い:)

0 以外の接続タイムアウトを設定してみてください。

conn.setConnectionTimeout( 3000);

.openConnection() の後に行う

final HttpURLConnection conn = (HttpURLConnection) sourceURL.openConnection();
conn.setConnectionTimeout( 3000);

0 以外の readTimeout も設定されていない場合。

conn.setReadTimeout( 3000);
于 2012-03-17T15:40:58.580 に答える