You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rest离线永久缓存问题:建议新增OFFLINE_FIRST缓存模式

实现“离线优先”的Rest缓存策略(跳过响应头缓存校验)

我完全懂你的痛点——要对无权限访问的远程服务器数据做永久离线缓存,而且不想依赖响应头里的Last-Modified或ETag做校验,就想优先用本地缓存,没有的话再联网拉取。可惜现有的CachingMode.MANUAL根本不是这个逻辑,你现在用的“先离线模式试一遍,404再切智能模式”的 workaround 虽然能解决问题,但确实有点折腾,新增一个CachingMode.OFFLINE_FIRST模式绝对是更优雅的解决方案。

你的当前实现逻辑是完全通顺的,先以OFFLINE模式尝试读取本地缓存:

Response<Map> response = Rest.get(url)
    .cacheMode(CachingMode.OFFLINE)
    .queryParam("param", value)
    .jsonContent()
    .onErrorCodeJSON(e -> { throw new RuntimeException(createErrorMessage(e)); })
    .onError(e -> {
        if (e.getResponseCode() == 0 || e.getConnectionRequest().getResponseCode() == 404) {
            is404 = true;
            return;
        }
        throw new RuntimeException("Network error. Please check your connection and try again.");
    })
    .timeout(6000)
    .getAsJsonMap();

如果缓存不存在(触发404或无响应),再切换到SMART模式去联网拉取并自动缓存结果:

if (is404) {
    is404 = false;
    response = Rest.get(url)
        .cacheMode(CachingMode.SMART)
        .queryParam("param", value)
        .jsonContent()
        .onErrorCodeJSON(e -> { throw new RuntimeException(createErrorMessage(e)); })
        .onError(e -> {
            throw new RuntimeException("Network error. Please check your connection and try again.");
        })
        .timeout(6000)
        .getAsJsonMap();
}

关于你提到的OFFLINE_FIRST模式,它的核心逻辑应该是:

  • 第一步:直接读取本地缓存,命中则立即返回,完全跳过网络请求
  • 第二步:如果缓存未命中,自动发起网络请求,并且强制将响应结果存入本地缓存(无需校验服务器返回的Last-Modified或ETag)
  • 第三步:返回网络请求的结果

这种模式刚好完美匹配你的需求,既能省去手动做两次请求的冗余代码,又能彻底脱离对服务器响应头缓存标识的依赖。如果这个Rest客户端是开源项目,你可以考虑提交Feature Request建议新增该模式;如果是你们内部封装的工具,那完全可以自己扩展实现这个CachingMode,把两次请求的逻辑封装到底层,对外只暴露简洁的OFFLINE_FIRST选项。

内容的提问来源于stack exchange,提问作者Diamond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:37:54