6

在我的 android 应用程序中,我试图缓存 Http Client 的响应。我正在使用 facebook graph api 测试此任务并具有以下网址:https ://graph.facebook.com/riz.ahmed.52

我第一次得到“first_name”并显示它。然后我更改我的 Facebook 个人资料的名字并再次调用相同的链接。我期待得到旧的/缓存的“first_name”,但我得到了更新的。当我调用 url 时,控制台总是显示“响应来自上游服务器”消息。

我的 Http Client 代码如下:

    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;
            }

我正在使用Android 2.3.3。请让我知道我在这里缺少什么

4

1 回答 1

4

您正在加载的页面指定了一个Expires:Sat, 01 Jan 2000 00:00:00 GMT标题,即它始终被认为是陈旧的,并且必须始终重新获取。

编辑

Pragma: no-cache显然也返回一个。基本上,它告诉你的 HTTP 客户端永远不要缓存这个页面。如果您对缓存响应一无所知,则可以使用HttpResponseInterceptor删除这些标头。

#2 编辑

使用http-clientcache-4.2.jar会有问题,因为它与 Android SDK 打包的 HTTP 客户端版本不完全兼容——NoClassDefFoundError使用它时你会得到 s 和类似的废话。

但是 - 如果您通过下载 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不幸的是final在 中的哪个CachingHttpClient,但是查看它会显示所有需要去使不可缓存的条目可缓存的标头。

于 2012-05-29T08:55:03.687 回答