我正在使用CachingHttpClientBuilder
通过HttpServlet
创建CloseableHttpClient
来获取内部资源。在大多数情况下,我希望它使用它的缓存,这似乎工作正常。但是,定期使用客户端检查特殊远程文件的更新(基本上它具有配置数据)。在这种情况下,我希望能够告诉客户端通过HTTP获取资源,即使缓存包含它并且它还没有被标记为陈旧。
当我在JavaScript中遇到这样的情况时,我经常附加一个伪造的查询字符串参数,其中包含时间戳,以便URL与缓存的条目不匹配。但是,我认为在这种情况下有更好的解决方案,因为我们可以直接以编程方式访问HTTP客户端。
为了避免有人建议只更改远程服务器,以便设置Cache-Control: no-cache
标头以防止这种情况,请理解这是我无法控制的。目标是在此实例中绕过缓存,无论远程服务器是否说它可以/应该缓存。
有人可能还建议在这种情况下不使用缓存HttpClient
,这样就行了,但对我来说似乎不太理想,因为那时我需要再做一次HttpClient
(其他部分)此应用程序需要缓存这些HTTP资源才能充分执行。
编辑:用户3360944建议使用HttpCacheInvalidator
,这可能是正确的解决方案,但我不确定如何执行此操作。有人可以举例说明在flushInvalidatedCacheEntries
方法中放置什么来删除给定URL的缓存条目吗? (我有特殊的URL,我从不想缓存)
new HttpCacheInvalidator() {
@Override
public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req) {
// What do I need to do here to invalidate a cached entry for
// say, http://www.example.com/path/file.txt?
}
@Override
public void flushInvalidatedCacheEntries(HttpHost host, HttpRequest request, HttpResponse response) {
// Do nothing here since I don't need to invalidate anything
// based on the response received
}
}
答案 0 :(得分:1)
由于您拥有CachingHttpClientBuilder,您可以将其配置为使用此方法使用特定的HttpCacheInvalidator
setHttpCacheInvalidator(HttpCacheInvalidator cacheInvalidator)
如果您需要未缓存版本的响应,可以使用HttpCachedInvalidator在发出请求之前使请求无效。
答案 1 :(得分:1)
它将涉及一些自定义代码,但可以通过略微调整HttpClient的执行管道来完全绕过缓存层
class ConditionalCachingExec implements ClientExecChain {
private final ClientExecChain mainExec;
private final ClientExecChain cachingExec;
public ConditionalCachingExec(final ClientExecChain mainExec, final ClientExecChain cachingExec) {
this.mainExec = mainExec;
this.cachingExec = cachingExec;
}
@Override
public CloseableHttpResponse execute(
final HttpRoute route,
final HttpRequestWrapper request,
final HttpClientContext clientContext,
final HttpExecutionAware execAware) throws IOException, HttpException {
URI uri = request.getURI();
if ("/stuff".equals(uri.getPath())) {
return mainExec.execute(route, request, clientContext, execAware);
} else {
return cachingExec.execute(route, request, clientContext, execAware);
}
}
};
class MyCachingHttpClientBuilder extends CachingHttpClientBuilder {
@Override
protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) {
ClientExecChain cachingExec = super.decorateMainExec(mainExec);
return new ConditionalCachingExec(mainExec, cachingExec);
}
};
CloseableHttpClient httpClient = new MyCachingHttpClientBuilder().build();