Java 有没有一种简单的方法可以手动强制缓存HttpClient 4.3.x绕过缓存?
我使用Java 有没有一种简单的方法可以手动强制缓存HttpClient 4.3.x绕过缓存?,java,apache-httpclient-4.x,Java,Apache Httpclient 4.x,我使用HttpServlet创建一个in来获取内部资源。在大多数情况下,我希望它使用它的缓存,这似乎工作得很好。但是,定期使用客户机检查特殊远程文件的更新(基本上它有配置数据)。在这种情况下,我希望能够告诉客户机通过HTTP获取资源,即使缓存中包含该资源并且该资源尚未标记为过时 当我在JavaScript中遇到这种情况时,我经常在其中附加一个带有时间戳的伪查询字符串参数,这样URL就不会与缓存条目匹配。然而,我认为在这种情况下有一个更好的解决方案,因为我们可以通过编程直接访问HTTP客户机 为了
HttpServlet
创建一个in来获取内部资源。在大多数情况下,我希望它使用它的缓存,这似乎工作得很好。但是,定期使用客户机检查特殊远程文件的更新(基本上它有配置数据)。在这种情况下,我希望能够告诉客户机通过HTTP获取资源,即使缓存中包含该资源并且该资源尚未标记为过时
当我在JavaScript中遇到这种情况时,我经常在其中附加一个带有时间戳的伪查询字符串参数,这样URL就不会与缓存条目匹配。然而,我认为在这种情况下有一个更好的解决方案,因为我们可以通过编程直接访问HTTP客户机
为了避免有人建议更改远程服务器,使其设置一个缓存控制:no Cache
头来防止这种情况,请理解这超出了我的控制范围。目标是在这个实例中绕过缓存,不管远程服务器是否说它可以/应该被缓存
在这种情况下,有人可能会建议不要使用缓存HttpClient
,这是可以的,但对我来说似乎不太理想,因为这样我就需要制作第二个HttpClient
(此应用程序的其他部分需要缓存这些HTTP资源才能充分发挥作用)
编辑:用户3360944建议使用,这可能是正确的解决方案,但我还不确定如何做到这一点。有人能举例说明在flushInvalidatedCacheEntries
方法中放置什么来删除给定URL的缓存条目吗?(我有一些我永远不想缓存的特定URL)
由于您有CachingHttpClientBuilder,因此可以将其配置为使用此方法的特定HttpCacheInvalidater
setHttpCacheInvalidator(HttpCacheInvalidator cacheInvalidator)
如果您想要响应的非缓存版本,可以使用HttpCachedInvalidator在发出请求之前使请求无效。这将涉及一些自定义代码,但是可以通过稍微调整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();
那么,既然我还没有提供一个
httpcacheinvalidater
,那么它是否自动使用了某种默认实现?如果是这样,添加一个会覆盖默认行为吗?也就是说,为了确保不破坏其他缓存,我需要多小心?我在CachingtPClientBuilder上找不到任何关于其标准缓存操作的文档,但我必须承认,这不是一次彻底的搜索。apache.org上有一个活动的、可公开访问的jira项目,我怀疑该项目网站上有更多的文档可以帮助您确定最佳方法。使用现有的HttpClient
(不是这样设置的)是否无法做到这一点?也就是说,我可以使用像user3360944建议的那样的httpcacheinvalidater
来执行此操作吗?否则,这似乎比只在我想绕过缓存的情况下使用非缓存客户端要复杂得多。@iX3:不,没有。构造后无法修改协议管道。
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();