簡體   English   中英

有一種簡單的方法可以手動強制緩存HttpClient 4.3.x繞過緩存嗎?

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

我正在使用CachingHttpClientBuilder通過HttpServlet創建一個CloseableHttpClient來獲取內部資源。 在大多數情況下,我希望它使用其緩存,這似乎運行良好。 但是,定期使用客戶端檢查對特殊遠程文件的更新(基本上它具有配置數據)。 在那種情況下,我希望能夠告訴客戶端通過HTTP來獲取資源,即使緩存中包含該資源並且該資源尚未標記為過期。

當我在JavaScript中遇到這種情況時,通常會在其中附加帶有時間戳的虛假查詢字符串參數,以使URL與緩存的條目不匹配。 但是,我認為在這種情況下會有更好的解決方案,因為我們可以直接以編程方式訪問HTTP客戶端。

以免有人建議僅更改遠程服務器,以便它設置Cache-Control: no-cache標頭來防止這種情況,請理解,這不在我的控制范圍之內。 目標是在這種情況下繞過緩存,而不管遠程服務器是否說可以/應該緩存。

有人可能還會建議在這種情況下不要使用緩存HttpClient ,但這對我來說並不理想,因為那樣的話,我就需要再創建一個HttpClient (此應用程序的其他部分需要對這些HTTP資源進行緩存才能表現良好)。

編輯 :user3360944建議使用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
    }
}

由於您具有CachingHttpClientBuilder,因此可以通過此方法將其配置為使用特定的HttpCacheInvalidator。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM