Java 使用SSL或TLSv1.2时,将忽略Apache HttpClient-keepalive
我将ApacheHttpClient 4.5用于我的soap Web服务 目前,我遇到了一个问题,在使用TLSv1.2时,httpclient中的keep-alive被忽略。但是,如果使用HTTP,则“保持活动”正在工作 你们有什么想法吗 我的代码如下所示: 主类:HttpClientPool.javaJava 使用SSL或TLSv1.2时,将忽略Apache HttpClient-keepalive,java,web-services,apache-httpclient-4.x,tls1.2,tcp-keepalive,Java,Web Services,Apache Httpclient 4.x,Tls1.2,Tcp Keepalive,我将ApacheHttpClient 4.5用于我的soap Web服务 目前,我遇到了一个问题,在使用TLSv1.2时,httpclient中的keep-alive被忽略。但是,如果使用HTTP,则“保持活动”正在工作 你们有什么想法吗 我的代码如下所示: 主类:HttpClientPool.java public class HttpClientPool { private static PoolingHttpClientConnectionManager manager = nu
public class HttpClientPool {
private static PoolingHttpClientConnectionManager manager = null;
private static CloseableHttpClient httpClient = null;
private static final Logger logger = Logger.getLogger(HttpClientPool.class);
public static synchronized CloseableHttpClient getHttpClient(){
if(httpClient==null){
//Some function to get SSLConnectionSocketFactory in Singleton
SSLConnectionSocketFactory sslConnSocFac = getSSLConnectionSocketFactory();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnSocFac)
.build();
HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connectionFactory = new ManagedHttpClientConnectionFactory(
DefaultHttpRequestWriterFactory.INSTANCE, DefaultHttpResponseParserFactory.INSTANCE);
DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;
manager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, connectionFactory, dnsResolver);
SocketConfig deaultSocketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
manager.setDefaultSocketConfig(deaultSocketConfig);
manager.setMaxTotal(300);
manager.setDefaultMaxPerRoute(200);
manager.setValidateAfterInactivity(50*1000);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(20*1000)
.setSocketTimeout(50*1000)
.setConnectionRequestTimeout(20000)
.build();
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse httpResponse, org.apache.http.protocol.HttpContext context) {
return 1000 * 1000;
}
};
httpClient = HttpClients.custom()
.setConnectionManager(manager)
.setConnectionManagerShared(false)
.evictIdleConnections(60l, TimeUnit.SECONDS)
.evictExpiredConnections()
.setConnectionTimeToLive(60, TimeUnit.SECONDS)
.setDefaultRequestConfig(defaultRequestConfig)
.setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE)
.setKeepAliveStrategy(myStrategy)
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
.build();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run(){
try {
httpClient1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
return httpClient;
}
private static SSLConnectionSocketFactory getSSLConnectionSocketFactory() {
//some working
return sslConnectionSocketFactory;
}
}
这里有两个选项:
#sendSOAPMessage
public class webServiceClient{
HttpClientPool httpClientPool;
private static final Logger logger = Logger.getLogger(HttpClientPool.class);
public sendSOAPMessage(String url, String soapAction, String userToken){
HttpPost post = new HttpPost(url);
HttpEntity entity = new ByteArrayEntity(xml.getBytes("UTF-8"));
post.setEntity(entity);
post.setHeader("Content-type", "application/soap+xml; charset=UTF-8");
post.setHeader("SOAPAction", soapAction);
post.setHeader("Connection", "Keep-Alive");
post.setHeader("Keep-Alive", "header");
HttpClientContext clientContext = HttpClientContext.create();
clientContext.setUserToken(userToken);
try (CloseableHttpResponse response = httpClientPool.getHttpClient().execute(post, clientContext)) {
String result = EntityUtils.toString(response.getEntity());
logger.info("Response: " + result);
EntityUtils.consume(response.getEntity());
}
}
}
httpClient = HttpClients.custom()
.disableConnectionState()
.build();
您的应用程序是否使用基于证书的客户端身份验证?嗨,ok2c,我想是的。我将做以下工作:1。将密钥库和信任库放入KeyManager和TrustManager 2中。将KeyManager和TrustManager放入SSLContext 3。通过放置SSLContext和协议为TLSv1.2 4来创建org.apache.http.conn.ssl.SSLConnectionSocketFactory。通过放置SSLConnectionSocketFactory创建PoolightTPClientConnectionManager。SSLConnectionSocketFactory不会解决您眼前的问题,但至少解释了为什么HttpClient不会重复使用不共享相同会话/执行上下文的持久连接。感谢您的反馈。我无法在同一执行上下文下使用httpclient,因为它是从另一个类调用的。实现类A->webServiceClient->HttpClientPool。或者您有一个HttpClientPool的示例可以在相同的执行上下文下使用吗?您好,ok2c,我已经尝试了这两种方法,并且工作得很好。我将使用第一个选项,因为它可以处理多个用户身份。非常感谢您的反馈。这对我真的很有帮助。
httpClient = HttpClients.custom()
.disableConnectionState()
.build();