RestTemplate提示 “I/O error on POST request for “https://xxxxx.com””

问题:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://www.xxxx.com/xxxx/xxxx/xxxx": Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out

本地环境信息:Mac OS 10.14.5、JDK8

测试环境信息:Docker Linux 3.10+、JDK8


场景:

今天有一个功能,需要调用远程API,使用的是RestTemplate,在本地单元测试调用无误后放到测试环境,发生了 read time out 的行为。

排查:

1.首先本地重试,并没有发生超时的timeout。

2.联想到由于是https请求,可能由于https证书的问题,于是配置了信任所有证书。(代码放最后)

3.代码里配置了信任所有证书,响应就正常了。

Conclusion

具体也没有很深入的了解,本地debug时,看到SSL握手之后服务端有返回证书,构造成X509对象,所以证书验证时是通过的,具体可以看:org.apache.http.conn.ssl.SSLConnectionSocketFactory#verifyHostname 方法

由于没有在Linux上跑,所以没有得到最终的结论,mark一下吧。
@Bean

public RestTemplate restTemplate (RestTemplateBuilder builder) throws NoSuchAlgorithmException, KeyManagementException {

    TrustManager[] trustAllCerts =new TrustManager[] {

            new X509TrustManager() {

                @Override

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {

                    return new X509Certificate[0];

}

                @Override

                public void checkClientTrusted(

                        java.security.cert.X509Certificate[] certs, String authType) {

}

                @Override

                public void checkServerTrusted(

                        java.security.cert.X509Certificate[] certs, String authType) {

}

}

};

    SSLContext sslContext =SSLContext.getInstance("SSL");

    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

    CloseableHttpClient httpClient =HttpClients.custom()

            .setSSLContext(sslContext)

            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)

            .build();

    HttpComponentsClientHttpRequestFactory customRequestFactory =new HttpComponentsClientHttpRequestFactory();

    customRequestFactory.setHttpClient(httpClient);

    RestTemplate restTemplate = builder.requestFactory(() ->customRequestFactory)

            .build();

    return builder.build();

}

你可能感兴趣的:(RestTemplate提示 “I/O error on POST request for “https://xxxxx.com””)