<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. Java配置類
java
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; }
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 HttpClientRestTemplateConfig { @Autowired private HttpPoolProperties httpPoolProperties; @Bean("httpClientRestTemplate") public RestTemplate httpClientRestTemplate() { HttpClient httpClient = httpClient(); ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); RestTemplate restTemplate = new RestTemplate(factory); // 能夠添加消息轉換 //restTemplate.setMessageConverters(...); // 能夠增長攔截器 //restTemplate.setInterceptors(...); return restTemplate; } @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()); // 設置路由(域名)對應的最大線程數,若是設置則比setDefaultMaxPerRoute(xxx)的優先級高 //connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("v2.moon.com", 80)), 20); // validateAfterInactivity 空閒永久鏈接檢查間隔,這個牽扯的還比較多, // 官方推薦使用這個來檢查永久連接的可用性,而不推薦每次請求的時候纔去檢查 connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity()); RequestConfig requestConfig = RequestConfig.custom() // 鏈接上服務器(握手成功)的時間(能夠設置2000),超出拋出connect timeout .setConnectTimeout(httpPoolProperties.getConnectTimeout()) // 服務器返回數據(response)的時間(能夠設置3000),超過拋出read timeout .setSocketTimeout(httpPoolProperties.getSocketTimeout()) // 從鏈接池中獲取鏈接的超時時間,超時間未拿到可用鏈接,會拋出如下異常 //org.apache.http.conn.ConnectionPoolTimeoutException: //Timeout waiting for connection from pool .setConnectionRequestTimeout(httpPoolProperties.getConnectionRequestTimeout()) .build(); // 重試一次 DefaultHttpRequestRetryHandler requestRetryHandler = new DefaultHttpRequestRetryHandler(1, true, new ArrayList<>()) { public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { LOGGER.info("Retry request, execution count: {}, exception: {}", executionCount, exception); return super.retryRequest(exception, executionCount, context); } }; return HttpClientBuilder.create() .setDefaultRequestConfig(requestConfig) .setConnectionManager(connectionManager) .setRetryHandler(requestRetryHandler) .build(); } }
3.使用方法web
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重載方法 //TestResponseEntity 爲自定義dto ResponseEntity<TestResponseEntity> entity = restTemplate.getForEntity("http://39.107.104.221/api/test/{1}", TestResponseEntity.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); } }