mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-10-07 15:14:38 +08:00
🎨 #3640 【微信支付】使用HttpClient发送http请求时调整为使用连接池的形式
This commit is contained in:
67
weixin-java-pay/CONNECTION_POOL.md
Normal file
67
weixin-java-pay/CONNECTION_POOL.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# HTTP连接池功能说明
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
`WxPayServiceApacheHttpImpl` 现在支持HTTP连接池功能,可以显著提高高并发场景下的性能表现。
|
||||||
|
|
||||||
|
## 主要改进
|
||||||
|
|
||||||
|
1. **连接复用**: 不再为每个请求创建新的HttpClient实例,而是复用连接池中的连接
|
||||||
|
2. **性能提升**: 减少连接建立和销毁的开销,提高吞吐量
|
||||||
|
3. **资源优化**: 合理控制并发连接数,避免资源浪费
|
||||||
|
4. **SSL支持**: 同时支持普通HTTP和SSL连接的连接池
|
||||||
|
|
||||||
|
## 配置说明
|
||||||
|
|
||||||
|
### 默认配置
|
||||||
|
```java
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
// 默认配置:
|
||||||
|
// maxConnTotal = 20 (最大连接数)
|
||||||
|
// maxConnPerRoute = 10 (每个路由最大连接数)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义配置
|
||||||
|
```java
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setMaxConnTotal(50); // 设置最大连接数
|
||||||
|
config.setMaxConnPerRoute(20); // 设置每个路由最大连接数
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
连接池功能是自动启用的,无需额外配置:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 1. 配置微信支付
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("your-app-id");
|
||||||
|
config.setMchId("your-mch-id");
|
||||||
|
config.setMchKey("your-mch-key");
|
||||||
|
|
||||||
|
// 2. 创建支付服务(连接池自动启用)
|
||||||
|
WxPayServiceApacheHttpImpl payService = new WxPayServiceApacheHttpImpl();
|
||||||
|
payService.setConfig(config);
|
||||||
|
|
||||||
|
// 3. 正常使用,所有HTTP请求都会使用连接池
|
||||||
|
WxPayUnifiedOrderResult result = payService.unifiedOrder(request);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 向后兼容性
|
||||||
|
|
||||||
|
- 此功能完全向后兼容,现有代码无需修改
|
||||||
|
- 如果不设置连接池参数,将使用默认配置
|
||||||
|
- 支持原有的HttpClientBuilderCustomizer自定义功能
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 连接池中的HttpClient实例会被复用,不要手动关闭
|
||||||
|
2. SSL连接和普通连接使用不同的连接池
|
||||||
|
3. 连接池参数建议根据实际并发量调整
|
||||||
|
4. 代理配置仍然正常工作
|
||||||
|
|
||||||
|
## 性能建议
|
||||||
|
|
||||||
|
- 对于高并发应用,建议适当增加`maxConnTotal`和`maxConnPerRoute`
|
||||||
|
- 监控连接池使用情况,避免连接数不足导致的阻塞
|
||||||
|
- 在容器环境中,注意连接池配置与容器资源限制的平衡
|
@@ -14,7 +14,16 @@ import lombok.ToString;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.RegExUtils;
|
import org.apache.commons.lang3.RegExUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.auth.AuthScope;
|
||||||
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
|
import org.apache.http.client.CredentialsProvider;
|
||||||
|
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
import org.apache.http.ssl.SSLContexts;
|
import org.apache.http.ssl.SSLContexts;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
@@ -185,11 +194,32 @@ public class WxPayConfig {
|
|||||||
|
|
||||||
|
|
||||||
private CloseableHttpClient apiV3HttpClient;
|
private CloseableHttpClient apiV3HttpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于普通支付接口的可复用HttpClient,使用连接池
|
||||||
|
*/
|
||||||
|
private CloseableHttpClient httpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于需要SSL证书的支付接口的可复用HttpClient,使用连接池
|
||||||
|
*/
|
||||||
|
private CloseableHttpClient sslHttpClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持扩展httpClientBuilder
|
* 支持扩展httpClientBuilder
|
||||||
*/
|
*/
|
||||||
private HttpClientBuilderCustomizer httpClientBuilderCustomizer;
|
private HttpClientBuilderCustomizer httpClientBuilderCustomizer;
|
||||||
private HttpClientBuilderCustomizer apiV3HttpClientBuilderCustomizer;
|
private HttpClientBuilderCustomizer apiV3HttpClientBuilderCustomizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP连接池最大连接数,默认20
|
||||||
|
*/
|
||||||
|
private int maxConnTotal = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP连接池每个路由的最大连接数,默认10
|
||||||
|
*/
|
||||||
|
private int maxConnPerRoute = 10;
|
||||||
/**
|
/**
|
||||||
* 私钥信息
|
* 私钥信息
|
||||||
*/
|
*/
|
||||||
@@ -498,4 +528,111 @@ public class WxPayConfig {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化使用连接池的HttpClient
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient
|
||||||
|
* @throws WxPayException 初始化异常
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient initHttpClient() throws WxPayException {
|
||||||
|
if (this.httpClient != null) {
|
||||||
|
return this.httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建连接池管理器
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
|
||||||
|
connectionManager.setMaxTotal(this.maxConnTotal);
|
||||||
|
connectionManager.setDefaultMaxPerRoute(this.maxConnPerRoute);
|
||||||
|
|
||||||
|
// 创建HttpClient构建器
|
||||||
|
org.apache.http.impl.client.HttpClientBuilder httpClientBuilder = HttpClients.custom()
|
||||||
|
.setConnectionManager(connectionManager);
|
||||||
|
|
||||||
|
// 配置代理
|
||||||
|
configureProxy(httpClientBuilder);
|
||||||
|
|
||||||
|
// 提供自定义httpClientBuilder的能力
|
||||||
|
Optional.ofNullable(httpClientBuilderCustomizer).ifPresent(e -> {
|
||||||
|
e.customize(httpClientBuilder);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.httpClient = httpClientBuilder.build();
|
||||||
|
return this.httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化使用连接池且支持SSL的HttpClient
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient
|
||||||
|
* @throws WxPayException 初始化异常
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient initSslHttpClient() throws WxPayException {
|
||||||
|
if (this.sslHttpClient != null) {
|
||||||
|
return this.sslHttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化SSL上下文
|
||||||
|
SSLContext sslContext = this.getSslContext();
|
||||||
|
if (null == sslContext) {
|
||||||
|
sslContext = this.initSSLContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建支持SSL的连接池管理器
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
|
||||||
|
connectionManager.setMaxTotal(this.maxConnTotal);
|
||||||
|
connectionManager.setDefaultMaxPerRoute(this.maxConnPerRoute);
|
||||||
|
|
||||||
|
// 创建HttpClient构建器,配置SSL
|
||||||
|
org.apache.http.impl.client.HttpClientBuilder httpClientBuilder = HttpClients.custom()
|
||||||
|
.setConnectionManager(connectionManager)
|
||||||
|
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier()));
|
||||||
|
|
||||||
|
// 配置代理
|
||||||
|
configureProxy(httpClientBuilder);
|
||||||
|
|
||||||
|
// 提供自定义httpClientBuilder的能力
|
||||||
|
Optional.ofNullable(httpClientBuilderCustomizer).ifPresent(e -> {
|
||||||
|
e.customize(httpClientBuilder);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sslHttpClient = httpClientBuilder.build();
|
||||||
|
return this.sslHttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置HTTP代理
|
||||||
|
*/
|
||||||
|
private void configureProxy(org.apache.http.impl.client.HttpClientBuilder httpClientBuilder) {
|
||||||
|
if (StringUtils.isNotBlank(this.getHttpProxyHost()) && this.getHttpProxyPort() > 0) {
|
||||||
|
if (StringUtils.isEmpty(this.getHttpProxyUsername())) {
|
||||||
|
this.setHttpProxyUsername("whatever");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用代理服务器 需要用户认证的代理服务器
|
||||||
|
CredentialsProvider provider = new BasicCredentialsProvider();
|
||||||
|
provider.setCredentials(new AuthScope(this.getHttpProxyHost(), this.getHttpProxyPort()),
|
||||||
|
new UsernamePasswordCredentials(this.getHttpProxyUsername(), this.getHttpProxyPassword()));
|
||||||
|
httpClientBuilder.setDefaultCredentialsProvider(provider)
|
||||||
|
.setProxy(new HttpHost(this.getHttpProxyHost(), this.getHttpProxyPort()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用于普通支付接口的HttpClient
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient getHttpClient() {
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用于SSL支付接口的HttpClient
|
||||||
|
*
|
||||||
|
* @return CloseableHttpClient
|
||||||
|
*/
|
||||||
|
public CloseableHttpClient getSslHttpClient() {
|
||||||
|
return sslHttpClient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -52,15 +52,15 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
|
|||||||
@Override
|
@Override
|
||||||
public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException {
|
public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException {
|
||||||
try {
|
try {
|
||||||
HttpClientBuilder httpClientBuilder = createHttpClientBuilder(useKey);
|
|
||||||
HttpPost httpPost = this.createHttpPost(url, requestStr);
|
HttpPost httpPost = this.createHttpPost(url, requestStr);
|
||||||
try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
|
CloseableHttpClient httpClient = this.createHttpClient(useKey);
|
||||||
final byte[] bytes = httpClient.execute(httpPost, ByteArrayResponseHandler.INSTANCE);
|
|
||||||
final String responseData = Base64.getEncoder().encodeToString(bytes);
|
// 使用连接池的客户端,不需要手动关闭
|
||||||
this.logRequestAndResponse(url, requestStr, responseData);
|
final byte[] bytes = httpClient.execute(httpPost, ByteArrayResponseHandler.INSTANCE);
|
||||||
wxApiData.set(new WxPayApiData(url, requestStr, responseData, null));
|
final String responseData = Base64.getEncoder().encodeToString(bytes);
|
||||||
return bytes;
|
this.logRequestAndResponse(url, requestStr, responseData);
|
||||||
}
|
wxApiData.set(new WxPayApiData(url, requestStr, responseData, null));
|
||||||
|
return bytes;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.logError(url, requestStr, e);
|
this.logError(url, requestStr, e);
|
||||||
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
|
wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage()));
|
||||||
@@ -71,17 +71,17 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
|
|||||||
@Override
|
@Override
|
||||||
public String post(String url, String requestStr, boolean useKey) throws WxPayException {
|
public String post(String url, String requestStr, boolean useKey) throws WxPayException {
|
||||||
try {
|
try {
|
||||||
HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey);
|
|
||||||
HttpPost httpPost = this.createHttpPost(url, requestStr);
|
HttpPost httpPost = this.createHttpPost(url, requestStr);
|
||||||
try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
|
CloseableHttpClient httpClient = this.createHttpClient(useKey);
|
||||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
|
||||||
String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
// 使用连接池的客户端,不需要手动关闭
|
||||||
this.logRequestAndResponse(url, requestStr, responseString);
|
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
||||||
if (this.getConfig().isIfSaveApiData()) {
|
String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||||
wxApiData.set(new WxPayApiData(url, requestStr, responseString, null));
|
this.logRequestAndResponse(url, requestStr, responseString);
|
||||||
}
|
if (this.getConfig().isIfSaveApiData()) {
|
||||||
return responseString;
|
wxApiData.set(new WxPayApiData(url, requestStr, responseString, null));
|
||||||
}
|
}
|
||||||
|
return responseString;
|
||||||
} finally {
|
} finally {
|
||||||
httpPost.releaseConnection();
|
httpPost.releaseConnection();
|
||||||
}
|
}
|
||||||
@@ -281,6 +281,26 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
|
|||||||
return apiV3HttpClient;
|
return apiV3HttpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseableHttpClient createHttpClient(boolean useKey) throws WxPayException {
|
||||||
|
if (useKey) {
|
||||||
|
// 使用SSL连接池客户端
|
||||||
|
CloseableHttpClient sslHttpClient = this.getConfig().getSslHttpClient();
|
||||||
|
if (null == sslHttpClient) {
|
||||||
|
this.getConfig().initSslHttpClient();
|
||||||
|
sslHttpClient = this.getConfig().getSslHttpClient();
|
||||||
|
}
|
||||||
|
return sslHttpClient;
|
||||||
|
} else {
|
||||||
|
// 使用普通连接池客户端
|
||||||
|
CloseableHttpClient httpClient = this.getConfig().getHttpClient();
|
||||||
|
if (null == httpClient) {
|
||||||
|
this.getConfig().initHttpClient();
|
||||||
|
httpClient = this.getConfig().getHttpClient();
|
||||||
|
}
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static StringEntity createEntry(String requestStr) {
|
private static StringEntity createEntry(String requestStr) {
|
||||||
return new StringEntity(requestStr, ContentType.create(APPLICATION_JSON, StandardCharsets.UTF_8));
|
return new StringEntity(requestStr, ContentType.create(APPLICATION_JSON, StandardCharsets.UTF_8));
|
||||||
//return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
|
//return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
|
||||||
|
@@ -0,0 +1,61 @@
|
|||||||
|
package com.github.binarywang.wxpay.service.impl;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 演示连接池功能的示例测试
|
||||||
|
*/
|
||||||
|
public class ConnectionPoolUsageExampleTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void demonstrateConnectionPoolUsage() throws Exception {
|
||||||
|
// 1. 创建配置并设置连接池参数
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("wx123456789");
|
||||||
|
config.setMchId("1234567890");
|
||||||
|
config.setMchKey("32位商户密钥32位商户密钥32位商户密钥");
|
||||||
|
|
||||||
|
// 设置连接池参数(可选,有默认值)
|
||||||
|
config.setMaxConnTotal(50); // 最大连接数,默认20
|
||||||
|
config.setMaxConnPerRoute(20); // 每个路由最大连接数,默认10
|
||||||
|
|
||||||
|
// 2. 初始化连接池
|
||||||
|
CloseableHttpClient pooledClient = config.initHttpClient();
|
||||||
|
Assert.assertNotNull(pooledClient);
|
||||||
|
|
||||||
|
// 3. 创建支付服务实例
|
||||||
|
WxPayServiceApacheHttpImpl payService = new WxPayServiceApacheHttpImpl();
|
||||||
|
payService.setConfig(config);
|
||||||
|
|
||||||
|
// 4. 现在所有的HTTP请求都会使用连接池
|
||||||
|
// 对于非SSL请求,会复用同一个HttpClient实例
|
||||||
|
CloseableHttpClient client1 = payService.createHttpClient(false);
|
||||||
|
CloseableHttpClient client2 = payService.createHttpClient(false);
|
||||||
|
Assert.assertSame(client1, client2, "非SSL请求应该复用同一个客户端实例");
|
||||||
|
|
||||||
|
// 对于SSL请求,也会复用同一个SSL HttpClient实例(需要配置证书后)
|
||||||
|
System.out.println("连接池配置成功!");
|
||||||
|
System.out.println("最大连接数:" + config.getMaxConnTotal());
|
||||||
|
System.out.println("每路由最大连接数:" + config.getMaxConnPerRoute());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void demonstrateDefaultConfiguration() throws Exception {
|
||||||
|
// 使用默认配置的示例
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("wx123456789");
|
||||||
|
config.setMchId("1234567890");
|
||||||
|
config.setMchKey("32位商户密钥32位商户密钥32位商户密钥");
|
||||||
|
|
||||||
|
// 不设置连接池参数,使用默认值
|
||||||
|
CloseableHttpClient client = config.initHttpClient();
|
||||||
|
Assert.assertNotNull(client);
|
||||||
|
|
||||||
|
// 验证默认配置
|
||||||
|
Assert.assertEquals(config.getMaxConnTotal(), 20, "默认最大连接数应该是20");
|
||||||
|
Assert.assertEquals(config.getMaxConnPerRoute(), 10, "默认每路由最大连接数应该是10");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,86 @@
|
|||||||
|
package com.github.binarywang.wxpay.service.impl;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||||
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试WxPayServiceApacheHttpImpl的连接池功能
|
||||||
|
*/
|
||||||
|
public class WxPayServiceApacheHttpImplConnectionPoolTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpClientConnectionPool() throws Exception {
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("test-app-id");
|
||||||
|
config.setMchId("test-mch-id");
|
||||||
|
config.setMchKey("test-mch-key");
|
||||||
|
|
||||||
|
// 测试初始化连接池
|
||||||
|
CloseableHttpClient httpClient1 = config.initHttpClient();
|
||||||
|
Assert.assertNotNull(httpClient1, "HttpClient should not be null");
|
||||||
|
|
||||||
|
// 再次获取,应该返回同一个实例
|
||||||
|
CloseableHttpClient httpClient2 = config.getHttpClient();
|
||||||
|
Assert.assertSame(httpClient1, httpClient2, "Should return the same HttpClient instance");
|
||||||
|
|
||||||
|
// 验证连接池配置
|
||||||
|
WxPayServiceApacheHttpImpl service = new WxPayServiceApacheHttpImpl();
|
||||||
|
service.setConfig(config);
|
||||||
|
|
||||||
|
// 测试不使用SSL的情况下应该使用连接池
|
||||||
|
CloseableHttpClient clientForNonSSL = service.createHttpClient(false);
|
||||||
|
Assert.assertSame(httpClient1, clientForNonSSL, "Should use pooled client for non-SSL requests");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSslHttpClientConnectionPool() throws Exception {
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("test-app-id");
|
||||||
|
config.setMchId("test-mch-id");
|
||||||
|
config.setMchKey("test-mch-key");
|
||||||
|
|
||||||
|
// 为了测试SSL客户端,我们需要设置一些基本的SSL配置
|
||||||
|
// 注意:在实际使用中需要提供真实的证书
|
||||||
|
try {
|
||||||
|
CloseableHttpClient sslClient1 = config.initSslHttpClient();
|
||||||
|
Assert.assertNotNull(sslClient1, "SSL HttpClient should not be null");
|
||||||
|
|
||||||
|
CloseableHttpClient sslClient2 = config.getSslHttpClient();
|
||||||
|
Assert.assertSame(sslClient1, sslClient2, "Should return the same SSL HttpClient instance");
|
||||||
|
|
||||||
|
WxPayServiceApacheHttpImpl service = new WxPayServiceApacheHttpImpl();
|
||||||
|
service.setConfig(config);
|
||||||
|
|
||||||
|
// 测试使用SSL的情况下应该使用SSL连接池
|
||||||
|
CloseableHttpClient clientForSSL = service.createHttpClient(true);
|
||||||
|
Assert.assertSame(sslClient1, clientForSSL, "Should use pooled SSL client for SSL requests");
|
||||||
|
|
||||||
|
} catch (WxPayException e) {
|
||||||
|
// SSL初始化失败是预期的,因为我们没有提供真实的证书
|
||||||
|
// 这里主要是测试代码路径是否正确
|
||||||
|
Assert.assertTrue(e.getMessage().contains("证书") || e.getMessage().contains("商户号"),
|
||||||
|
"Should fail with certificate or merchant ID related error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnectionPoolConfiguration() throws Exception {
|
||||||
|
WxPayConfig config = new WxPayConfig();
|
||||||
|
config.setAppId("test-app-id");
|
||||||
|
config.setMchId("test-mch-id");
|
||||||
|
config.setMchKey("test-mch-key");
|
||||||
|
config.setMaxConnTotal(50);
|
||||||
|
config.setMaxConnPerRoute(20);
|
||||||
|
|
||||||
|
CloseableHttpClient httpClient = config.initHttpClient();
|
||||||
|
Assert.assertNotNull(httpClient, "HttpClient should not be null");
|
||||||
|
|
||||||
|
// 验证配置值是否正确设置
|
||||||
|
Assert.assertEquals(config.getMaxConnTotal(), 50, "Max total connections should be 50");
|
||||||
|
Assert.assertEquals(config.getMaxConnPerRoute(), 20, "Max connections per route should be 20");
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user