apache httpclient cache 實現可緩存的http客戶端


這里的cache storage 采用ehcache,而不是默認的內存式的cache storage。采用ehcache可以將內容緩存到磁盤上。

maven

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient-cache</artifactId>
            <version>4.5</version>
        </dependency>


        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.8.3</version>
        </dependency>

 

ehcache配置如下:

<ehcache>
    <!-- <diskStore path="java.io.tmpdir" /> -->
    
    <diskStore path="c:\\ehcache"/>
    
    <defaultCache 
        maxElementsInMemory="10000" 
        eternal="false"
        timeToIdleSeconds="120" 
        timeToLiveSeconds="120" 
        overflowToDisk="true"
        maxElementsOnDisk="10000000" 
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120" 
        memoryStoreEvictionPolicy="LRU" />


    <cache name="httpCache" 
        maxElementsInMemory="10000" 
        eternal="true"
        timeToIdleSeconds="0" 
        timeToLiveSeconds="0"  
        overflowToDisk="true"
        maxElementsOnDisk="10000000" 
        diskPersistent="true"
        diskExpiryThreadIntervalSeconds="120" 
        memoryStoreEvictionPolicy="LRU" />
</ehcache>

這里有兩個關鍵點:一是將eternal設置為true,表示采用非內存式的緩存;二是將diskPersistent設置為true,表示將緩存持久化到硬盤。


測試的代碼如下:

package my.httpClient;

import java.io.IOException;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.DiskStoreConfiguration;
import net.sf.ehcache.config.PersistenceConfiguration;
import net.sf.ehcache.config.PersistenceConfiguration.Strategy;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;

import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.cache.CacheResponseStatus;
import org.apache.http.client.cache.HttpCacheContext;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.cache.CacheConfig;
import org.apache.http.impl.client.cache.CachingHttpClients;
import org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage;

public class EhCacheTest1 {

    public static void main(String[] args) throws ClientProtocolException,
            IOException {

        System.out.println("begin");

        // EhCache緩存存儲
        CacheManager cacheManager = CacheManager.create();
        Cache httpCache = cacheManager.getCache("httpCache");

        // 定義httpclient的緩存存儲
        EhcacheHttpCacheStorage ehcacheHttpCacheStorage = new EhcacheHttpCacheStorage(
                httpCache);

        // 緩存配置
        CacheConfig cacheConfig = CacheConfig.custom()
                .setMaxCacheEntries(10000).setMaxObjectSize(819200).build();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(30000).setSocketTimeout(30000).build();

        HttpHost proxy = new HttpHost("127.0.0.1", 8888);

        CloseableHttpClient cachingClient = CachingHttpClients.custom()
                .setCacheConfig(cacheConfig)
                .setHttpCacheStorage(ehcacheHttpCacheStorage)
                .setDefaultRequestConfig(requestConfig).setProxy(proxy).build();

        HttpCacheContext context = HttpCacheContext.create();
        HttpGet httpget = new HttpGet("http://test.cn:11677/api/values?id=8888");

        CloseableHttpResponse response = cachingClient
                .execute(httpget, context);
        try {
            CacheResponseStatus responseStatus = context
                    .getCacheResponseStatus();
            switch (responseStatus) {
            case CACHE_HIT:
                System.out
                        .println("A response was generated from the cache with "
                                + "no requests sent upstream");
                break;
            case CACHE_MODULE_RESPONSE:
                System.out
                        .println("The response was generated directly by the "
                                + "caching module");
                break;
            case CACHE_MISS:
                System.out.println("The response came from an upstream server");
                break;
            case VALIDATED:
                System.out.println("The response was generated from the cache "
                        + "after validating the entry with the origin server");
                break;
            }
        } catch (Exception e) {
            // TODO: handle exception

        } finally {
             response.close();
             cacheManager.shutdown();        
             System.out.println("end");
        }
    }

}

以上代碼有幾個需要說明的地方:

(1)服務端需要遵循RFC2626中規定緩存方面的協議。

(2)代碼setHttpCacheStorage(ehcacheHttpCacheStorage)用於設置緩存存儲。

(3)代碼setProxy(proxy)用於配置代理,當你使用fiddler進行調試的時候,這個很有用。若不采用代理,則可以將這句給去掉。

(4)代碼cacheManager.shutdown()用於關閉cacheManager,記得一定要執行這一句,否則會報錯。      

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM