6

私のAndroidアプリケーションでは、Httpクライアントの応答をキャッシュしようとしています。私はFacebookグラフAPIを使用してこのタスクをテストしており、次のURLを持っています:https ://graph.facebook.com/riz.ahmed.52

初めて「first_name」を取得して表示します。次に、Facebookプロファイルの名を変更して、同じリンクをもう一度呼び出します。古い/キャッシュされた「first_name」を取得することを期待していますが、更新されたものを取得します。URLを呼び出すと、コンソールに常に「応答はアップストリームサーバーから送信されました」というメッセージが表示されます。

Httpクライアントの私のコードは次のとおりです。

    CacheConfig cacheConfig = new CacheConfig();  
    cacheConfig.setMaxCacheEntries(1000);
    cacheConfig.setMaxObjectSizeBytes(8192);

    //HttpClient httpclient = new CachingHttpClient(new DefaultHttpClient(), cacheConfig);
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();

    // Updated code [START]
    httpclient.addResponseInterceptor(new HttpResponseInterceptor() {
        public void process(
            final HttpResponse response,
            final HttpContext context) throws HttpException, IOException {

                 response.removeHeader(response.getFirstHeader("Pragma"));
                 response.removeHeader(response.getFirstHeader("Expires"));

            }                
        });
    // Updated code [END]

    HttpGet httpget = new HttpGet(url);

            // Execute HTTP Get Request
    HttpResponse response = httpclient.execute(httpget, localContext);
    HttpEntity entity = response.getEntity();
    String res = EntityUtils.getContentCharSet(entity);

    CacheResponseStatus responseStatus = (CacheResponseStatus) localContext.getAttribute(
        CachingHttpClient.CACHE_RESPONSE_STATUS);

    switch (responseStatus) {
        case CACHE_HIT:
            System.out.println("A response was generated from the cache with no requests " +
                "sent upstream");
            break;
        case CACHE_MODULE_RESPONSE:
                System.out.println("The response was generated directly by the caching module");
                break;
        case CACHE_MISS:
                System.out.println("The response came from an upstream server");
                break;
        case VALIDATED:
                System.out.println("The response was generated from the cache after validating " +
                        "the entry with the origin server");
                break;
            }

私はAndroid2.3.3を使用しています。ここで欠けているものを教えてください

4

1 に答える 1

4

読み込んでいるページにはヘッダーが指定されていますExpires:Sat, 01 Jan 2000 00:00:00 GMT。つまり、ヘッダーは常に古いと見なされ、常に再取得する必要があります。

編集

Pragma: no-cacheまた明らかに a を返します。基本的に、このページを決してキャッシュしないように HTTP クライアントに指示しています。応答のキャッシュに行き詰まっている場合は、 HttpResponseInterceptorを使用してこれらのヘッダーを削除できる場合があります。

#2編集

http-clientcache-4.2.jarAndroid SDK にパッケージ化された HTTP クライアントのバージョンと完全に互換性がないため、使用すると問題が発生する可能性がありますNoClassDefFoundError

ただし、 clientcache-4.2 のソースをダウンロードして「独自にビルド」し、満たされていない参照 (コモンズ ロギングのパッケージ名のリファクタリングなど) を取り除き、コード全体に散らばっているすべての注釈を削除した場合 (. ) おそらく動作するバージョンを入手できます。もしそうなら、これはうまくいきました:

class MakeCacheable implements HttpResponseInterceptor {
    public static MakeCacheable INSTANCE = new MakeCacheable();
    public void process(HttpResponse resp, HttpContext ctx) throws HttpException, IOException {
        resp.removeHeaders("Expires");
        resp.removeHeaders("Pragma");
        resp.removeHeaders("Cache-Control");
    }
}

DefaultHttpClientなどによって使用されるCachingHttpClientように注入されます。

DefaultHttpClient realClient = new DefaultHttpClient();
realClient.addResponseInterceptor(MakeCacheable.INSTANCE, 0); // This goes first
CachingHttpClient httpClient = new CachingHttpClient(realClient, cacheConfig);

エントリがキャッシュされるかどうかは、ResponseCachingPolicy残念ながらの によって決定されますfinalCachingHttpClient、それを調べると、キャッシュできないエントリをキャッシュ可能にするために必要なすべてのヘッダーが表示されます。

于 2012-05-29T08:55:03.687 に答える