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
相关产品推荐
相关产品推荐

