Apache HttpClient 4.5 在Springboot中使用
阿新 • • 發佈:2020-10-10
ConnectionRequestTimeout
httpclient使用連線池來管理連線,這個時間就是從連線池獲取連線的超時時間,可以想象下資料庫連線池
ConnectTimeout
連線建立時間,三次握手完成時間
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.12</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.13</version> </dependency>
然後新建httpclient類:
在dopost中可以根據業務自定義邏輯
@Slf4j @Service public class HttpClientFactory { @Autowired HttpClientConfig httpClientConfig; private PoolingHttpClientConnectionManager poolConnManager; // 執行緒安全,所有的執行緒都可以使用它一起傳送http請求 private CloseableHttpClient httpClient; @PostConstruct public void init() { try { log.info("init http client start, default config is {}", httpClientConfig); SSLConnectionSocketFactory trustAll = buildSSLContext(); // 配置同時支援 HTTP 和 HTTPS // 一個httpClient物件對於https僅會選用一個SSLConnectionSocketFactory Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create(). register("http", PlainConnectionSocketFactory.getSocketFactory()). register("https", trustAll).build(); // 初始化連線管理器 poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); poolConnManager.setMaxTotal(httpClientConfig.getPollMaxTotal());// 同時最多連線數 // 設定最大路由 poolConnManager.setDefaultMaxPerRoute(httpClientConfig.getPollMaxPeerRouter()); httpClient = getConnection(); log.info("init http client finish"); } catch (Exception e) { log.error("", e); } } public CloseableHttpClient getConnection() { RequestConfig config = RequestConfig.custom().setConnectTimeout(httpClientConfig.getConnectTimeout()) .setConnectionRequestTimeout(httpClientConfig.getConnectionRequestTimeout()) .setSocketTimeout(httpClientConfig.getResponseTimeout()) .build(); return HttpClients.custom() // 設定連線池管理 .setConnectionManager(poolConnManager) .setDefaultRequestConfig(config).build(); } public String doGet(String url) { return this.doGet(url, Collections.EMPTY_MAP, Collections.EMPTY_MAP); } public String doGet(String url, Map<String, Object> params) { return this.doGet(url, Collections.EMPTY_MAP, params); } public String doGet(String url, Map<String, String> headers, Map<String, Object> params) { // *) 構建GET請求頭 String apiUrl = getUrlWithParams(url, params); HttpGet httpGet = new HttpGet(apiUrl); // *) 設定header資訊 if (headers != null && headers.size() > 0) { for (Map.Entry<String, String> entry : headers.entrySet()) { httpGet.addHeader(entry.getKey(), entry.getValue()); } } try (CloseableHttpResponse response = httpClient.execute(httpGet)) { if (response == null || response.getStatusLine() == null) { return null; } int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { HttpEntity entityRes = response.getEntity(); if (entityRes != null) { return EntityUtils.toString(entityRes, "UTF-8"); } } return null; } catch (IOException e) { log.error("", e); } return null; } public HttpServerResponseDTO doPost(String apiUrl, String body, int connectionTimeOut, Integer contentTypeEnum, String pemBody) { return doPost(apiUrl, Collections.EMPTY_MAP, body, connectionTimeOut, contentTypeEnum); } public HttpServerResponseDTO doPost(String apiUrl, Map<String, String> headers, String body,Integer contentTypeEnum) { CloseableHttpClient currentHttpClient = httpClient; HttpPost httpPost = new HttpPost(apiUrl); // *) 配置請求headers if (headers != null && headers.size() > 0) { for (Map.Entry<String, String> entry : headers.entrySet()) { httpPost.addHeader(entry.getKey(), entry.getValue()); } } ContentTypeEnum contentType = ContentTypeEnum.getDataSourceEnum(contentTypeEnum); // *) 配置請求引數 httpPost.setEntity(new StringEntity(body, ContentType.create(contentType.getDesc(), Consts.UTF_8))); httpPost.setConfig(buildRequestConfig()); try (CloseableHttpResponse response = currentHttpClient.execute(httpPost)) { if (response == null || response.getStatusLine() == null) { return HttpServerResponseDTO.builder() .statusCode(Constants.HTTP_CLIENT_ERROR) .build(); } HttpEntity httpEntity = response.getEntity(); String contentTypeString = httpEntity.getContentType() == null ? null : httpEntity.getContentType().getValue(); String connection = getHeaderValue(response, "Connection"); String server = getHeaderValue(response, "Server"); String date = getHeaderValue(response, "Date"); String pragma = getHeaderValue(response, "pragma"); return HttpServerResponseDTO.builder() .statusCode(response.getStatusLine().getStatusCode()) .body(EntityUtils.toString(response.getEntity(), UTF_8)) .contentType(contentTypeString) .connection(connection) .server(server) .date(date) .pragma(pragma) .build(); } catch (IOException e) { log.error("", e); return HttpServerResponseDTO.builder().statusCode(Constants.HTTP_CLIENT_ERROR).statusMessage(e.getMessage()).build(); } } private String getUrlWithParams(String url, Map<String, Object> params) { boolean first = true; StringBuilder sb = new StringBuilder(url); for (String key : params.keySet()) { char ch = '&'; if (first) { ch = '?'; first = false; } String value = params.get(key).toString(); try { String sval = URLEncoder.encode(value, "UTF-8"); sb.append(ch).append(key).append("=").append(sval); } catch (UnsupportedEncodingException e) { log.error("", e); } } return sb.toString(); } public SSLConnectionSocketFactory buildSSLContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException { SSLContext sslcontext = SSLContexts.custom() //忽略掉對伺服器端證書的校驗 .loadTrustMaterial((TrustStrategy) (chain, authType) -> true) .build(); return new SSLConnectionSocketFactory( sslcontext, new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE); } private RequestConfig buildRequestConfig() { int connectionOut = httpClientConfig.getConnectTimeout(); return RequestConfig.custom().setConnectTimeout(connectionOut) .setConnectionRequestTimeout(httpClientConfig.getConnectionRequestTimeout()) .setSocketTimeout(connectionOut) .build(); } private String getHeaderValue(CloseableHttpResponse response, String key) { return response.getFirstHeader(key) == null ? null : response.getFirstHeader(key).getValue(); } }
呼叫方式:
@Autowired
HttpClientFactory httpClientFactory;
HttpServerResponseDTO httpServerResponseDTO = httpClientFactory.doPost(url, headersMap, body, httpConfigEntity.getContentType(), httpConfigEntity.getTls());