Apache HttpClient - 使用SSL或TLSv1.2时会忽略keepalive

问题描述 投票:0回答:1

我正在使用Apache HttpClient 4.5作为我的soap webservice。

目前,我遇到了一个问题,当使用TLSv1.2时,会忽略httpclient中的keep alive。但是,如果使用HTTP,则保持活动状态正常。

你们对它有什么想法吗?

我的代码如下所示:

主类:HttpClientPool.java

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;
    }

}

触发类:webServiceClient.java

public class webServiceClient{

    HttpClientPool httpClientPool;

    private static final Logger logger = Logger.getLogger(HttpClientPool.class);

    public sendSOAPMessage(String url, String soapAction){
        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");

        CloseableHttpResponse response = httpClientPool.getHttpClient().execute(post);
        String result = EntityUtils.toString(response.getEntity());
        logger.info("Response: " + result);

        EntityUtils.consume(response.getEntity());
        response.close();
    }
}
java web-services apache-httpclient-4.x tls1.2 tcp-keepalive
1个回答
1
投票

你有两个选择:

  1. 将用户令牌(在您的情况下应该是用户证书的CN)传递给#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()); } } }
  2. 如果您确定您的应用程序不必支持多个用户身份,请禁用连接状态跟踪。 httpClient = HttpClients.custom() .disableConnectionState() .build();
© www.soinside.com 2019 - 2024. All rights reserved.