springboot使用RestTemplate+httpclient鏈接池發送http消息

簡介

  1. RestTemplate是spring支持的一個請求http rest服務的模板對象,性質上有點像jdbcTemplate
  2. RestTemplate底層仍是使用的httpclient(org.apache.http.client.HttpClient)發送請求的
  3. HttpClient能夠作鏈接池,而發送消息的工具類能夠使用RestTemplate,因此若是你的項目需求http鏈接池,RestTemplate+httpclient鏈接池是一種不錯的方式,能夠節省開發工做,也能夠更優雅的使用。

 

配置

  1. maven依賴
    <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.6</version>
    </dependency>
    
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

      

  2. Java配置類



    package com.jinjian.rt.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    @Component
    @ConfigurationProperties(prefix = "http-pool")
    @Data
    public class HttpPoolProperties {
    
        private Integer maxTotal;
        private Integer defaultMaxPerRoute;
        private Integer connectTimeout;
        private Integer connectionRequestTimeout;
        private Integer socketTimeout;
        private Integer validateAfterInactivity;
    
    }
    

      



    package com.jinjian.rt.config;
    
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class RestTemplateConfig {
    
        @Autowired
        private HttpPoolProperties httpPoolProperties;
    
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate(httpRequestFactory());
        }
    
        @Bean
        public ClientHttpRequestFactory httpRequestFactory() {
            return new HttpComponentsClientHttpRequestFactory(httpClient());
        }
    
        @Bean
        public HttpClient httpClient() {
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", SSLConnectionSocketFactory.getSocketFactory())
                    .build();
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
            connectionManager.setMaxTotal(httpPoolProperties.getMaxTotal());
            connectionManager.setDefaultMaxPerRoute(httpPoolProperties.getDefaultMaxPerRoute());
            connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity());
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(httpPoolProperties.getSocketTimeout()) //服務器返回數據(response)的時間,超過拋出read timeout
                    .setConnectTimeout(httpPoolProperties.getConnectTimeout()) //鏈接上服務器(握手成功)的時間,超出拋出connect timeout
                    .setConnectionRequestTimeout(httpPoolProperties.getConnectionRequestTimeout())//從鏈接池中獲取鏈接的超時時間,超時間未拿到可用鏈接,會拋出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                    .build();
            return HttpClientBuilder.create()
                    .setDefaultRequestConfig(requestConfig)
                    .setConnectionManager(connectionManager)
                    .build();
        }
    }
    

      

  3. 使用方法java

    package com.jinjian.rt.service;
    
    import com.jinjian.rt.dto.RuiooResponseEntity;
    import org.json.JSONException;
    import org.json.JSONObject;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    import java.io.IOException;
    
    @Service
    public class TestService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        public void startTest() throws JSONException, IOException {
    
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("first","jinjian");
            jsonObject.put("second","aaaaaaa");
    
            long start = System.currentTimeMillis();
            //{1} 表示第一個佔位符,也能夠填寫name,可是這是另外一個getForEntity重載方法
            //RuiooResponseEntity 爲自定義dto
            ResponseEntity<RuiooResponseEntity> entity = restTemplate.getForEntity("http://39.107.104.221/api/test/{1}", RuiooResponseEntity.class, 123);
            long end = System.currentTimeMillis();
            long cost = end - start;
            System.out.println("耗時:"+cost);
            RuiooResponseEntity body = entity.getBody();
            body.getData();
            body.getStatus();
            body.getMessage();
            System.out.println("響應體:"+ body);
        }
    }
    
相關文章
相關標籤/搜索