首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FileNotFoundException在使用HttpResponsecache的脱机缓存时

FileNotFoundException在使用HttpResponsecache的脱机缓存时
EN

Stack Overflow用户
提问于 2013-12-26 17:18:37
回答 1查看 930关注 0票数 1

我使用HttpResponseCache在我的android应用程序中启用响应缓存(用于web请求),并且离线缓存无法工作。我正在执行文档要求我做的离线缓存。

在我的应用程序类中,在onCreate方法中,我打开缓存时:

代码语言:javascript
复制
try {
    long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
    File httpCacheDir = new File(getCacheDir(), "http");
    Class.forName("android.net.http.HttpResponseCache")
        .getMethod("install", File.class, long.class)
        .invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {}

在我的HttpConnection类中,我使用以下方法获得JSON:

代码语言:javascript
复制
private String sendHttpGet(boolean cacheOnly) throws Exception {

    URL url = new URL(getUrlCompleta());
    HttpURLConnection urlConnection = null;
    String retorno = null;

    try {
        urlConnection = (HttpURLConnection) url.openConnection();
        if(urlConnection == null)
            throw new Exception("Conn obj is null");

        fillHeaders(urlConnection, cacheOnly);
        InputStream in = new BufferedInputStream(urlConnection.getInputStream(), 8192);
        retorno = convertStream(in);
        in.close();
        urlConnection.disconnect();

        if(retorno != null)
            return retorno;
    } catch(IOException e) {
        throw e;
    } finally {
        if(urlConnection != null)
            urlConnection.disconnect();
    }
    throw new Exception();
}

其中,convertStream方法只是将一个InputStream解析为一个String。方法fillHeaders在请求上放置一个令牌(出于安全原因),如果参数cacheOnly是true,则将标头"Cache-Control", "only-if-cached"添加到请求头(代码:connection.addRequestProperty("Cache-Control", "only-if-cached");)中。

当存在连接时,缓存工作“很好”(有一些奇怪的行为),并且应用程序访问web服务器只是为了查看是否有更新版本的JSON。当web服务器回答“什么都没有改变”时,缓存就会工作。

问题是当我没有连接并且使用头"Cache-Control", "only-if-cached"时。在这种情况下,我会收到一个java.io.FileNotFoundException: https://api.example.com/movies.json。这很尴尬,因为缓存的实施代码可能将响应存储在请求url上使用散列函数命名的文件中,而不是url本身。

有人知道我能做什么或者我的实现有什么问题吗?

ps:上面,我说“可能使用散列函数”,因为我找不到com.android.okhttp.HttpResponseCache对象的实现( android.net.http.HttpResponseCache委托缓存调用的类)。如果有人找到了,请告诉我在哪里看:)

ps2:即使我在Cache-Control头中添加了一个max-stale参数,它仍然不能工作。

ps3:很明显,我在api 14+上测试了它。

Https://“:虽然我访问的是一个"http://”URL地址“,但当该URL只是一个普通的”http://“地址”时,也会发生相同的行为。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-15 16:20:43

事实证明,问题在于我的web服务器所给出的响应中Cache-control指令的Cache-control值。它具有以下值:Cache-Control: max-age=0, private, must-revalidate。有了这个指令,我的服务器就会对缓存说,即使响应已经存在了0秒钟,也可以从缓存中使用。所以,我的连接没有使用任何缓存的响应。

知道最大年龄是在秒内指定的,我所要做的就是将值更改为:Cache-Control: max-age=600, private, must-revalidate!在这里,现在我有一个10分钟的缓存。

编辑:如果您想使用陈旧的响应,使用请求的max-stale指令,就不应该像我在with服务器中那样在响应中使用must-revalidate指令。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20788568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档