apache httpclient cache 实现可缓存的http客户端

蔚落 2022-01-31 01:47 255阅读 0赞

转自: https://www.cnblogs.com/dehai/p/5063106.html

这里的cache storage 采用ehcache,而不是默认的内存式的cache storage。采用ehcache可以将内容缓存到磁盘上。

maven

复制代码

  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpclient</artifactId>
  4. <version>4.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.httpcomponents</groupId>
  8. <artifactId>httpclient-cache</artifactId>
  9. <version>4.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>net.sf.ehcache</groupId>
  13. <artifactId>ehcache</artifactId>
  14. <version>2.8.3</version>
  15. </dependency>

复制代码

ehcache配置如下:

复制代码

  1. <ehcache>
  2. <!-- <diskStore path="java.io.tmpdir" /> -->
  3. <diskStore path="c:\\ehcache"/>
  4. <defaultCache
  5. maxElementsInMemory="10000"
  6. eternal="false"
  7. timeToIdleSeconds="120"
  8. timeToLiveSeconds="120"
  9. overflowToDisk="true"
  10. maxElementsOnDisk="10000000"
  11. diskPersistent="false"
  12. diskExpiryThreadIntervalSeconds="120"
  13. memoryStoreEvictionPolicy="LRU" />
  14. <cache name="httpCache"
  15. maxElementsInMemory="10000"
  16. eternal="true"
  17. timeToIdleSeconds="0"
  18. timeToLiveSeconds="0"
  19. overflowToDisk="true"
  20. maxElementsOnDisk="10000000"
  21. diskPersistent="true"
  22. diskExpiryThreadIntervalSeconds="120"
  23. memoryStoreEvictionPolicy="LRU" />
  24. </ehcache>

复制代码

这里有两个关键点:一是将eternal设置为true,表示采用非内存式的缓存;二是将diskPersistent设置为true,表示将缓存持久化到硬盘。

测试的代码如下:

复制代码

  1. package my.httpClient;
  2. import java.io.IOException;
  3. import net.sf.ehcache.Cache;
  4. import net.sf.ehcache.CacheManager;
  5. import net.sf.ehcache.config.CacheConfiguration;
  6. import net.sf.ehcache.config.Configuration;
  7. import net.sf.ehcache.config.DiskStoreConfiguration;
  8. import net.sf.ehcache.config.PersistenceConfiguration;
  9. import net.sf.ehcache.config.PersistenceConfiguration.Strategy;
  10. import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
  11. import org.apache.http.HttpHost;
  12. import org.apache.http.client.ClientProtocolException;
  13. import org.apache.http.client.cache.CacheResponseStatus;
  14. import org.apache.http.client.cache.HttpCacheContext;
  15. import org.apache.http.client.config.RequestConfig;
  16. import org.apache.http.client.methods.CloseableHttpResponse;
  17. import org.apache.http.client.methods.HttpGet;
  18. import org.apache.http.impl.client.CloseableHttpClient;
  19. import org.apache.http.impl.client.cache.CacheConfig;
  20. import org.apache.http.impl.client.cache.CachingHttpClients;
  21. import org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage;
  22. public class EhCacheTest1 {
  23. public static void main(String[] args) throws ClientProtocolException,
  24. IOException {
  25. System.out.println("begin");
  26. // EhCache缓存存储
  27. CacheManager cacheManager = CacheManager.create();
  28. Cache httpCache = cacheManager.getCache("httpCache");
  29. // 定义httpclient的缓存存储
  30. EhcacheHttpCacheStorage ehcacheHttpCacheStorage = new EhcacheHttpCacheStorage(
  31. httpCache);
  32. // 缓存配置
  33. CacheConfig cacheConfig = CacheConfig.custom()
  34. .setMaxCacheEntries(10000).setMaxObjectSize(819200).build();
  35. RequestConfig requestConfig = RequestConfig.custom()
  36. .setConnectTimeout(30000).setSocketTimeout(30000).build();
  37. HttpHost proxy = new HttpHost("127.0.0.1", 8888);
  38. CloseableHttpClient cachingClient = CachingHttpClients.custom()
  39. .setCacheConfig(cacheConfig)
  40. .setHttpCacheStorage(ehcacheHttpCacheStorage)
  41. .setDefaultRequestConfig(requestConfig).setProxy(proxy).build();
  42. HttpCacheContext context = HttpCacheContext.create();
  43. HttpGet httpget = new HttpGet("http://test.cn:11677/api/values?id=8888");
  44. CloseableHttpResponse response = cachingClient
  45. .execute(httpget, context);
  46. try {
  47. CacheResponseStatus responseStatus = context
  48. .getCacheResponseStatus();
  49. switch (responseStatus) {
  50. case CACHE_HIT:
  51. System.out
  52. .println("A response was generated from the cache with "
  53. + "no requests sent upstream");
  54. break;
  55. case CACHE_MODULE_RESPONSE:
  56. System.out
  57. .println("The response was generated directly by the "
  58. + "caching module");
  59. break;
  60. case CACHE_MISS:
  61. System.out.println("The response came from an upstream server");
  62. break;
  63. case VALIDATED:
  64. System.out.println("The response was generated from the cache "
  65. + "after validating the entry with the origin server");
  66. break;
  67. }
  68. } catch (Exception e) {
  69. // TODO: handle exception
  70. } finally {
  71. response.close();
  72. cacheManager.shutdown();
  73. System.out.println("end");
  74. }
  75. }
  76. }

复制代码

以上代码有几个需要说明的地方:

(1)服务端需要遵循RFC2626中规定缓存方面的协议。

(2)代码setHttpCacheStorage(ehcacheHttpCacheStorage)用于设置缓存存储。

(3)代码setProxy(proxy)用于配置代理,当你使用fiddler进行调试的时候,这个很有用。若不采用代理,则可以将这句给去掉。

(4)代码cacheManager.shutdown()用于关闭cacheManager,记得一定要执行这一句,否则会报错。

发表评论

表情:
评论列表 (有 0 条评论,255人围观)

还没有评论,来说两句吧...

相关阅读

    相关 缓存客户缓存

    客户端缓存相对于其他端的缓存而言,要简单一些,而且通常使和服务端以及网络侧的应用或缓存配合使用的。对于互联网应用而言,也就是通常所说的所说的BS架构应用,可以分为页面缓存和浏览