简体   繁体   English

有一种简单的方法可以手动强制缓存HttpClient 4.3.x绕过缓存吗?

[英]Is there an easy way to manually force a caching HttpClient 4.3.x to bypass the cache?

I am using CachingHttpClientBuilder to create a CloseableHttpClient in by an HttpServlet to fetch internal resources. 我正在使用CachingHttpClientBuilder通过HttpServlet创建一个CloseableHttpClient来获取内部资源。 In most cases I want it to use its cache, and that seems to be working fine. 在大多数情况下,我希望它使用其缓存,这似乎运行良好。 However, periodically the client is used to check for updates to a special remote file (basically it has configuration data). 但是,定期使用客户端检查对特殊远程文件的更新(基本上它具有配置数据)。 In that case, I would like to be able to tell the client to fetch the resource via HTTP even if the cache contains it and it isn't marked as stale yet. 在那种情况下,我希望能够告诉客户端通过HTTP来获取资源,即使缓存中包含该资源并且该资源尚未标记为过期。

When I've run into situations like this in JavaScript I have often appended a bogus query string parameter with a timestamp in it so that the URL would not match a cached entry. 当我在JavaScript中遇到这种情况时,通常会在其中附加带有时间戳的虚假查询字符串参数,以使URL与缓存的条目不匹配。 However, I would think there is a better solution in this case since we have direct, programmatic access to the HTTP client. 但是,我认为在这种情况下会有更好的解决方案,因为我们可以直接以编程方式访问HTTP客户端。

Lest someone suggest just changing the remote server so that it sets a Cache-Control: no-cache header to prevent this, please understand that this is outside of my control. 以免有人建议仅更改远程服务器,以便它设置Cache-Control: no-cache标头来防止这种情况,请理解,这不在我的控制范围之内。 The goal is to bypass the cache in this instance regardless of whether or not the remote server says it can/should be cached. 目标是在这种情况下绕过缓存,而不管远程服务器是否说可以/应该缓存。

Someone might also suggest not using a caching HttpClient in this case, which would be OK, but it seems less than ideal to me because then I would need to make a second HttpClient (other portions of this application require caching of these HTTP resources in order to perform sufficiently well). 有人可能还会建议在这种情况下不要使用缓存HttpClient ,但这对我来说并不理想,因为那样的话,我就需要再创建一个HttpClient (此应用程序的其他部分需要对这些HTTP资源进行缓存才能表现良好)。

EDIT : user3360944 suggested using a HttpCacheInvalidator , which may be the right solution, but I am not sure yet how to do this. 编辑 :user3360944建议使用HttpCacheInvalidator ,这可能是正确的解决方案,但是我不确定如何做到这一点。 Could someone give an example of what to put in the flushInvalidatedCacheEntries method to remove a cached entry for a given URL? 有人可以举一个例子,说明将什么放入flushInvalidatedCacheEntries方法中,以删除给定URL的缓存条目吗? (I have particular URLs that I never want to cache) (我有一些我不想缓存的特定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
    }
}

Since you have the CachingHttpClientBuilder, you can configure it to use a specific HttpCacheInvalidator with this method 由于您具有CachingHttpClientBuilder,因此可以通过此方法将其配置为使用特定的HttpCacheInvalidator。

setHttpCacheInvalidator(HttpCacheInvalidator cacheInvalidator) 

You can use the HttpCachedInvalidator to invalidate a request prior to issuing it if you want the uncached version of the response. 如果需要响应的未缓存版本,则可以在发出请求之前使用HttpCachedInvalidator使请求无效。

It will involve a bit of custom code but one can bypass the caching layer entirely by slightly tweaking HttpClient's execution pipeline 它将涉及一些自定义代码,但是可以通过稍微调整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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 4.3.x 重用 HttpClient 连接 - HttpClient connection reusing with 4.3.x 在HttpClient 4.3.x中更正基本身份验证 - Correct Basic Authentication in HttpClient 4.3.x 如何在httpClient 4.3.x中强制http客户端不自动处理身份验证挑战? - How to force the http client to not handle the authentication challenges automatically in httpClient 4.3.x? 使用HttpClient 4.3.x,为特定URL执行HttpHead会产生NoHttpResponseException - With HttpClient 4.3.x, executing a HttpHead for a specific URL gives NoHttpResponseException apache httpclient 4.4:HostnameVerifier从4.3.x过渡 - apache httpclient 4.4: HostnameVerifier transition from 4.3.x 使用非ASCII凭据在httpclient 4.3.x中不起作用 - Use of non-ascii credentials not working in httpclient 4.3.x HttpClient 4.3.x,修复不推荐使用的代码以使用当前的 HttpClient 实现 - HttpClient 4.3.x, fixing deprecated code to use current HttpClient implementations 带有Hibernate 4.3.x的BoneCP - BoneCP with Hibernate 4.3.x 获取Apache httpconents HttpClient 4.3.x OSGi包以解决Apache Karaf 2.3.x的问题 - Problems with getting Apache httpcomponents HttpClient 4.3.x OSGi bundle to work on Apache Karaf 2.3.x 如何使用Ajax从网页上使用httpclient 4.3.x获取信息 - how to use httpclient 4.3.x grabbing infomation from web page with ajax
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM