最近在项目开发中遇到了一个问题,用restTemplate调用https接口的时候一直掉不通,报错I/O error on POST request for “xxxx”: Remote host terminated the handshake;nested exception is javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake 远程主机终止了握手

一开始以为是SSL证书的问题。在百度上找了半天,千篇一律都是在RestTemplate实例化时加忽略证书。当然我也是加了忽略证书的,但是还是一直报那个错…

最后找到原因: 因为我访问的是国外的网站,我设置的代理ip是本机127.0.0.1;所以网络一直掉不通。

解决: 配置文件中将地址改为使用代理服务器的ip端口就可以了(没有可以买一个或者挂梯子)

下面附上完整的RestTemplateUtils实例化代码:

@Component

public class RestTemplateUtils {

private static HttpProxyProperties httpProxyProperties;

RestTemplateUtils(HttpProxyProperties properties) {

httpProxyProperties = properties;

}

@SneakyThrows

public static RestTemplate getInstance(String charset) {

TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

//忽略证书

SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()

.loadTrustMaterial(null, acceptingTrustStrategy)

.build();

SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

Registry registry = RegistryBuilder.create()

.register("http", PlainConnectionSocketFactory.getSocketFactory())

.register("https", csf)

.build();

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);

//连接池的最大连接数,0代表不限;如果取0,需要考虑连接泄露导致系统崩溃的后果

connectionManager.setMaxTotal(1000);

//每个路由的最大连接数,如果只调用一个地址,可以将其设置为最大连接数

connectionManager.setDefaultMaxPerRoute(300);

HttpClientBuilder clientBuilder = HttpClients.custom();

if (Objects.nonNull(httpProxyProperties) && Boolean.TRUE.equals(httpProxyProperties.getEnabled())) {

HttpHost proxy = new HttpHost(httpProxyProperties.getIp(), httpProxyProperties.getPort());

clientBuilder.setProxy(proxy);

}

CloseableHttpClient httpClient = clientBuilder.setConnectionManager(connectionManager)

.build();

HttpComponentsClientHttpRequestFactory requestFactory =

new HttpComponentsClientHttpRequestFactory();

requestFactory.setHttpClient(httpClient);

requestFactory.setConnectionRequestTimeout(10000);

requestFactory.setConnectTimeout(10000);

requestFactory.setReadTimeout(30000);

RestTemplate restTemplate = new RestTemplate(requestFactory);

List> list = restTemplate.getMessageConverters();

for (HttpMessageConverter httpMessageConverter : list) {

if (httpMessageConverter instanceof StringHttpMessageConverter) {

((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset));

break;

}

}

return restTemplate;

}

}

HttpProxyProperties代码:

@Data

@Component

@ConfigurationProperties(prefix = "http.proxy")

public class HttpProxyProperties {

private Boolean enabled;

private String ip;

private Integer port;

}

使用:

private static RestTemplate restTemplate = RestTemplateUtils.getInstance("utf-8");

问题解决,希望能够帮到你

查看原文