|
14 | 14 | import lombok.extern.slf4j.Slf4j; |
15 | 15 | import org.apache.commons.lang3.RegExUtils; |
16 | 16 | import org.apache.commons.lang3.StringUtils; |
| 17 | +import org.apache.http.HttpHost; |
| 18 | +import org.apache.http.auth.AuthScope; |
| 19 | +import org.apache.http.auth.UsernamePasswordCredentials; |
| 20 | +import org.apache.http.client.CredentialsProvider; |
| 21 | +import org.apache.http.impl.client.BasicCredentialsProvider; |
17 | 22 | import org.apache.http.impl.client.CloseableHttpClient; |
| 23 | +import org.apache.http.impl.client.HttpClients; |
| 24 | +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
| 25 | +import org.apache.http.conn.ssl.DefaultHostnameVerifier; |
| 26 | +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
18 | 27 | import org.apache.http.ssl.SSLContexts; |
19 | 28 |
|
20 | 29 | import javax.net.ssl.SSLContext; |
@@ -185,11 +194,32 @@ public class WxPayConfig { |
185 | 194 |
|
186 | 195 |
|
187 | 196 | private CloseableHttpClient apiV3HttpClient; |
| 197 | + |
| 198 | + /** |
| 199 | + * 用于普通支付接口的可复用HttpClient,使用连接池 |
| 200 | + */ |
| 201 | + private CloseableHttpClient httpClient; |
| 202 | + |
| 203 | + /** |
| 204 | + * 用于需要SSL证书的支付接口的可复用HttpClient,使用连接池 |
| 205 | + */ |
| 206 | + private CloseableHttpClient sslHttpClient; |
| 207 | + |
188 | 208 | /** |
189 | 209 | * 支持扩展httpClientBuilder |
190 | 210 | */ |
191 | 211 | private HttpClientBuilderCustomizer httpClientBuilderCustomizer; |
192 | 212 | private HttpClientBuilderCustomizer apiV3HttpClientBuilderCustomizer; |
| 213 | + |
| 214 | + /** |
| 215 | + * HTTP连接池最大连接数,默认20 |
| 216 | + */ |
| 217 | + private int maxConnTotal = 20; |
| 218 | + |
| 219 | + /** |
| 220 | + * HTTP连接池每个路由的最大连接数,默认10 |
| 221 | + */ |
| 222 | + private int maxConnPerRoute = 10; |
193 | 223 | /** |
194 | 224 | * 私钥信息 |
195 | 225 | */ |
@@ -498,4 +528,111 @@ private Object[] p12ToPem() { |
498 | 528 | return null; |
499 | 529 |
|
500 | 530 | } |
| 531 | + |
| 532 | + /** |
| 533 | + * 初始化使用连接池的HttpClient |
| 534 | + * |
| 535 | + * @return CloseableHttpClient |
| 536 | + * @throws WxPayException 初始化异常 |
| 537 | + */ |
| 538 | + public CloseableHttpClient initHttpClient() throws WxPayException { |
| 539 | + if (this.httpClient != null) { |
| 540 | + return this.httpClient; |
| 541 | + } |
| 542 | + |
| 543 | + // 创建连接池管理器 |
| 544 | + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); |
| 545 | + connectionManager.setMaxTotal(this.maxConnTotal); |
| 546 | + connectionManager.setDefaultMaxPerRoute(this.maxConnPerRoute); |
| 547 | + |
| 548 | + // 创建HttpClient构建器 |
| 549 | + org.apache.http.impl.client.HttpClientBuilder httpClientBuilder = HttpClients.custom() |
| 550 | + .setConnectionManager(connectionManager); |
| 551 | + |
| 552 | + // 配置代理 |
| 553 | + configureProxy(httpClientBuilder); |
| 554 | + |
| 555 | + // 提供自定义httpClientBuilder的能力 |
| 556 | + Optional.ofNullable(httpClientBuilderCustomizer).ifPresent(e -> { |
| 557 | + e.customize(httpClientBuilder); |
| 558 | + }); |
| 559 | + |
| 560 | + this.httpClient = httpClientBuilder.build(); |
| 561 | + return this.httpClient; |
| 562 | + } |
| 563 | + |
| 564 | + /** |
| 565 | + * 初始化使用连接池且支持SSL的HttpClient |
| 566 | + * |
| 567 | + * @return CloseableHttpClient |
| 568 | + * @throws WxPayException 初始化异常 |
| 569 | + */ |
| 570 | + public CloseableHttpClient initSslHttpClient() throws WxPayException { |
| 571 | + if (this.sslHttpClient != null) { |
| 572 | + return this.sslHttpClient; |
| 573 | + } |
| 574 | + |
| 575 | + // 初始化SSL上下文 |
| 576 | + SSLContext sslContext = this.getSslContext(); |
| 577 | + if (null == sslContext) { |
| 578 | + sslContext = this.initSSLContext(); |
| 579 | + } |
| 580 | + |
| 581 | + // 创建支持SSL的连接池管理器 |
| 582 | + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); |
| 583 | + connectionManager.setMaxTotal(this.maxConnTotal); |
| 584 | + connectionManager.setDefaultMaxPerRoute(this.maxConnPerRoute); |
| 585 | + |
| 586 | + // 创建HttpClient构建器,配置SSL |
| 587 | + org.apache.http.impl.client.HttpClientBuilder httpClientBuilder = HttpClients.custom() |
| 588 | + .setConnectionManager(connectionManager) |
| 589 | + .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier())); |
| 590 | + |
| 591 | + // 配置代理 |
| 592 | + configureProxy(httpClientBuilder); |
| 593 | + |
| 594 | + // 提供自定义httpClientBuilder的能力 |
| 595 | + Optional.ofNullable(httpClientBuilderCustomizer).ifPresent(e -> { |
| 596 | + e.customize(httpClientBuilder); |
| 597 | + }); |
| 598 | + |
| 599 | + this.sslHttpClient = httpClientBuilder.build(); |
| 600 | + return this.sslHttpClient; |
| 601 | + } |
| 602 | + |
| 603 | + /** |
| 604 | + * 配置HTTP代理 |
| 605 | + */ |
| 606 | + private void configureProxy(org.apache.http.impl.client.HttpClientBuilder httpClientBuilder) { |
| 607 | + if (StringUtils.isNotBlank(this.getHttpProxyHost()) && this.getHttpProxyPort() > 0) { |
| 608 | + if (StringUtils.isEmpty(this.getHttpProxyUsername())) { |
| 609 | + this.setHttpProxyUsername("whatever"); |
| 610 | + } |
| 611 | + |
| 612 | + // 使用代理服务器 需要用户认证的代理服务器 |
| 613 | + CredentialsProvider provider = new BasicCredentialsProvider(); |
| 614 | + provider.setCredentials(new AuthScope(this.getHttpProxyHost(), this.getHttpProxyPort()), |
| 615 | + new UsernamePasswordCredentials(this.getHttpProxyUsername(), this.getHttpProxyPassword())); |
| 616 | + httpClientBuilder.setDefaultCredentialsProvider(provider) |
| 617 | + .setProxy(new HttpHost(this.getHttpProxyHost(), this.getHttpProxyPort())); |
| 618 | + } |
| 619 | + } |
| 620 | + |
| 621 | + /** |
| 622 | + * 获取用于普通支付接口的HttpClient |
| 623 | + * |
| 624 | + * @return CloseableHttpClient |
| 625 | + */ |
| 626 | + public CloseableHttpClient getHttpClient() { |
| 627 | + return httpClient; |
| 628 | + } |
| 629 | + |
| 630 | + /** |
| 631 | + * 获取用于SSL支付接口的HttpClient |
| 632 | + * |
| 633 | + * @return CloseableHttpClient |
| 634 | + */ |
| 635 | + public CloseableHttpClient getSslHttpClient() { |
| 636 | + return sslHttpClient; |
| 637 | + } |
501 | 638 | } |
0 commit comments