zoukankan      html  css  js  c++  java
  • 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,记得一定要执行这一句,否则会报错。      

  • 相关阅读:
    go语言的运行时支持到底是多线程还是单线程
    丑数
    把数组排成最小数
    连续子数组的最大和
    最小的k个数
    数组中出现次数超过一半的数字
    字符串的排序
    二叉搜索树与双向链表
    复杂链表的赋值
    二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/dehai/p/5063106.html
Copyright © 2011-2022 走看看