如何正确使用HttpClient以及restTemplate

摘要:
importjava.util.concurrent.TimeUnit;importorg.apache.http.HeaderElement;importorg.apache.http.HeaderElementIterator;importorg.apache.http.HttpResponse;importorg.apache.http.client.HttpClient;importorg
importjava.util.concurrent.TimeUnit;

importorg.apache.http.HeaderElement;
importorg.apache.http.HeaderElementIterator;
importorg.apache.http.HttpResponse;
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.config.RequestConfig;
importorg.apache.http.config.Registry;
importorg.apache.http.config.RegistryBuilder;
importorg.apache.http.conn.ConnectionKeepAliveStrategy;
importorg.apache.http.conn.socket.ConnectionSocketFactory;
importorg.apache.http.conn.socket.PlainConnectionSocketFactory;
importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;
importorg.apache.http.impl.client.HttpClients;
importorg.apache.http.impl.conn.PoolingHttpClientConnectionManager;
importorg.apache.http.message.BasicHeaderElementIterator;
importorg.apache.http.protocol.HTTP;
importorg.apache.http.protocol.HttpContext;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.http.client.ClientHttpRequestFactory;
importorg.springframework.http.client.HttpComponentsClientHttpRequestFactory;
importorg.springframework.web.client.RestTemplate;

@Configuration
public classRestTemplateConfig {

    @Autowired
    privateRestTemplateProperties restTemplateProperties;

    @Bean
    publicRestTemplate restTemplate() {
        return newRestTemplate(httpRequestFactory());
    }

    @Bean
    publicClientHttpRequestFactory httpRequestFactory() {
        return newHttpComponentsClientHttpRequestFactory(httpClient());
    }

    //pool监测线程,定期移除过期连接、空闲连接/*public static class IdleConnectionMonitorThread extends Thread {

        private final HttpClientConnectionManager connMgr;

        public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
            super();
            this.connMgr = connMgr;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    synchronized (this) {
                        Thread.sleep(5000);
                        connMgr.closeExpiredConnections();
                        connMgr.closeIdleConnections(5, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
*/@Bean
    publicHttpClient httpClient() {
        //支持http和https
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory()).build();
        PoolingHttpClientConnectionManager connectionManager = newPoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal());
        connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getDefaultMaxPerRoute());
        connectionManager.setValidateAfterInactivity(restTemplateProperties.getValidateAfterInactivity());

        RequestConfig requestConfig =RequestConfig.custom()
                .setConnectTimeout(restTemplateProperties.getConnectTimeout())
                .setSocketTimeout(restTemplateProperties.getSocketTimeout())
                .setConnectionRequestTimeout(restTemplateProperties.getConnectionRequestTimeout()).build();

        //keep-alive策略
        ConnectionKeepAliveStrategy keepAliveStrategy = newConnectionKeepAliveStrategy() {
            @Override
            public longgetKeepAliveDuration(HttpResponse response, HttpContext context) {
                //如果服务端response返回了Keep-Alive header
                HeaderElementIterator it = newBasicHeaderElementIterator(
                        response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while(it.hasNext()) {
                    HeaderElement he =it.nextElement();
                    String param =he.getName();
                    String value =he.getValue();
                    if (value != null && param.equalsIgnoreCase("timeout")) {
                        try{
                            return Long.parseLong(value) * 1000;
                        } catch(NumberFormatException ignore) {
                        }
                    }
                }
                //否则设置客户端默认keep-alive超时时间
                returnrestTemplateProperties.getClientDefaultKeepAliveTime();
            }
        };

        /*Thread t = new IdleConnectionMonitorThread(connectionManager);
         t.setName("httpconnections-pool-evict-thread"); 
         t.start();
         */
        returnHttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .evictExpiredConnections()    //设置后台线程剔除失效连接
.evictIdleConnections(restTemplateProperties.getMaxIdleTime(), TimeUnit.MILLISECONDS)
                .setKeepAliveStrategy(keepAliveStrategy).build();
    }
}
importorg.springframework.boot.context.properties.ConfigurationProperties;
importorg.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix="resttemplate")
public classRestTemplateProperties {
    
    private Integer maxTotal;    //总连接数
    private Integer defaultMaxPerRoute; //单个路由最大连接数
    private Integer connectTimeout;        //与远程服务器建立连接的时间
    private Integer connectionRequestTimeout;    //从connection manager获取连接的超时时间
    private Integer socketTimeout;    //建立连接之后,等待远程服务器返回数据的时间,也就是两个数据包(请求包和响应包)之间不活动的最大时间
    privateInteger validateAfterInactivity;
    private Integer clientDefaultKeepAliveTime; //客户端默认keep-alive时间
    private Integer maxIdleTime;    //连接最大空闲时间
    publicInteger getMaxTotal() {
        returnmaxTotal;
    }
    public voidsetMaxTotal(Integer maxTotal) {
        this.maxTotal =maxTotal;
    }
    publicInteger getDefaultMaxPerRoute() {
        returndefaultMaxPerRoute;
    }
    public voidsetDefaultMaxPerRoute(Integer defaultMaxPerRoute) {
        this.defaultMaxPerRoute =defaultMaxPerRoute;
    }
    publicInteger getConnectTimeout() {
        returnconnectTimeout;
    }
    public voidsetConnectTimeout(Integer connectTimeout) {
        this.connectTimeout =connectTimeout;
    }
    publicInteger getConnectionRequestTimeout() {
        returnconnectionRequestTimeout;
    }
    public voidsetConnectionRequestTimeout(Integer connectionRequestTimeout) {
        this.connectionRequestTimeout =connectionRequestTimeout;
    }
    publicInteger getSocketTimeout() {
        returnsocketTimeout;
    }
    public voidsetSocketTimeout(Integer socketTimeout) {
        this.socketTimeout =socketTimeout;
    }
    publicInteger getValidateAfterInactivity() {
        returnvalidateAfterInactivity;
    }
    public voidsetValidateAfterInactivity(Integer validateAfterInactivity) {
        this.validateAfterInactivity =validateAfterInactivity;
    }
    publicInteger getClientDefaultKeepAliveTime() {
        returnclientDefaultKeepAliveTime;
    }
    public voidsetClientDefaultKeepAliveTime(Integer clientDefaultKeepAliveTime) {
        this.clientDefaultKeepAliveTime =clientDefaultKeepAliveTime;
    }
    publicInteger getMaxIdleTime() {
        returnmaxIdleTime;
    }
    public voidsetMaxIdleTime(Integer maxIdleTime) {
        this.maxIdleTime =maxIdleTime;
    }
    
}
resttemplate.max-total=2000resttemplate.default-max-per-route=1000resttemplate.connect-timeout=5000resttemplate.connection-request-timeout=1000resttemplate.socket-timeout=5000resttemplate.validate-after-inactivity=2000resttemplate.client-default-keep-alive-time=5000resttemplate.max-idle-time=5000

参考:http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html

https://www.cnblogs.com/meiwangqing/p/10712829.html

免责声明:文章转载自《如何正确使用HttpClient以及restTemplate》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇4、在centos7上使用consul时,yml配置文件:USACO 1.3 Wormholes下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

给HttpClient添加Socks代理

本文描述http client使用socks代理过程中需要注意的几个方面:1,socks5支持用户密码授权;2,支持https;3,支持让代理服务器解析DNS; 使用代理创建Socket 从原理上来看,不管用什么http客户端(httpclient,okhttp),最终都要转换到java.net.Socket的创建上去,看到代码: package java...

RestTemplate 发送 get 请求使用误区 多个参数传值为null

RestTemplate 发送 get 请求使用误区 多个参数传值为null(转载) 首先看一下官方文档是怎么描述的,传递多个值的情况(注意例子中用到的@pathParam,一般要用@queryParam) RestTemplate 实例 @Configuration public class RestConfiguration { @...

【转】.NET Core开发日志——IHttpClientFactory

当需要向某特定URL地址发送HTTP请求并得到相应响应时,通常会用到HttpClient类。该类包含了众多有用的方法,可以满足绝大多数的需求。但是如果对其使用不当时,可能会出现意想不到的事情。 博客园官方团队就遇上过这样的问题,国外博主也记录过类似的情况,YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILI...

Java 中使用 HttpClient 4.3.6 进行文件上传

代码部分 import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity....

4--SpringCloud-Ribbon/OpenFeign周阳老师

2021:4--SpringCloud-Ribbon/OpenFeign https://www.cnblogs.com/coderD/p/14350076.html SpringCloud https://www.cnblogs.com/coderD/p/14350073.html SpringCloud 和 Eureka https://www.cnb...

httpClient带一个或多个参数实现

 听课视频:https://www.bilibili.com/video/av68932809?p=5 思路分析:先创建httpClient对象,再通过URIBuilder对象根上网址,最后一步带上一个多个参数。 如何写一个HttpClient[1]——URI的处理   1核心代码分: //1:创建httpClient对象CloseableHttpClie...