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();