1

下面是我的配置

java 版本 "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, 混合模式)

使用Apache httpclient v4.4调用Restful服务,服务URL有有效证书(SHA2)

使用 apache httpclient 我们正在调用该服务。下面是代码

private static CloseableHttpClient appHttpClient() throws Exception {
    if (null != httpclient) {
        return httpclient;
    }
    final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
            .<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(trustAllSSLContext())).build();

    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    cm.setMaxTotal(HTTP_MAX_CON);
    cm.setDefaultMaxPerRoute(HTTP_CON_ROUTE);

    final RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(HTTP_CON_TO)
            .setConnectionRequestTimeout(HTTP_REQ_CON_TO).setSocketTimeout(HTTP_SO_TO).build();

    // final SSLConnectionSocketFactory factory = new
    // SSLConnectionSocketFactory(getSSLContext());

    httpclient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();

    return httpclient;
}

public static SSLContext trustAllSSLContext() throws Exception {
    if (sslContext != null) {
        return sslContext;
    }
    sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    System.out.println(
            "SSLContext :: Protocol :: " + sslContext.getProtocol() + " Provider :: " + sslContext.getProvider());
    return sslContext;
}

服务调用间歇性地失败,有批处理在循环中调用我们的服务,比如对服务的 30 次调用,所以其中一些失败,其中一些成功,对于失败的调用,我们得到低于异常。

java.lang.IllegalStateException: SSLContextImpl is not initialized
   at sun.security.ssl.SSLContextImpl.engineGetSocketFactory(SSLContextImpl.java:181)
   at javax.net.ssl.SSLContext.getSocketFactory(SSLContext.java:294)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:262)
   at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(SSLConnectionSocketFactory.java:205)
   at com.wdpr.payment.helper.HttpHelper.appHttpClient(HttpHelper.java:63)
   at com.wdpr.payment.helper.HttpHelper.makePostCall(HttpHelper.java:142)...

任何人都知道为什么它会间歇性地因这个异常而失败。

4

2 回答 2

1

如果“服务 URL 具有有效证书”为真 - 只需删除所有与 SSL 相关的自定义项。

这个(相信他们所有的方法):

new SSLConnectionSocketFactory(trustAllSSLContext())

实际上是对无效证书的破解,作为快速修复 - 尝试将 ' synchronized' 添加到trustAllSSLContext方法中。

于 2020-01-26T02:11:00.753 回答
1

在网上找到的代码片段中,

sslContext = SSLContext.getInstance("");

用“SSL”而不是“TLSv1.2”调用。

为了强制 ssl 套接字使用 TLSv1.2,我使用 了 How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS?

(编辑)

在可能相关的说明中,当使用 Http Commons MultiThreadedHttpConnectionManager 时,我们必须调用

manager.closeIdleConnections(10000); 
manager.deleteClosedConnections();

在每次 http 调用之后,否则我们每 N 次调用都会尝试一些连接失败。

于 2017-03-23T19:31:10.383 回答