1. 问题
使用RestTemplate调用Http API时,服务器是TLS1.0,但是客户端Java默认禁止TLS1.0,会报错:org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://10.255.200.114/health": The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]; nested exception is javax.net.ssl.SSLHandshakeException: The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]
2. 解决
-
修改java.security文件
bash# 以MacOS为例 vi /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/conf/security/java.security # 将TLSv1.0 从jdk.tls.disabledAlgorithms中删除 jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ include jdk.disabled.namedCurves
-
RestTemplate代码
javapublic RestTemplate restTemplate() { SSLConnectionSocketFactory scsf = null; try { scsf = new SSLConnectionSocketFactory( SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), NoopHostnameVerifier.INSTANCE); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (KeyManagementException e) { throw new RuntimeException(e); } catch (KeyStoreException e) { throw new RuntimeException(e); } Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", scsf) .build(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); connectionManager.setMaxTotal(200); connectionManager.setDefaultMaxPerRoute(100); connectionManager.setValidateAfterInactivity(1000); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(45000) .setConnectTimeout(45000) // Timeout waiting for connection from pool .setConnectionRequestTimeout(45000) .build(); ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create() .setDefaultRequestConfig(requestConfig) .setConnectionManager(connectionManager) .build()); return new RestTemplate(factory); }