javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
使用的版本:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> |
解决方法:
如果不是必须有证书,可以绕过HTTPS证书校验,可以用下面方法。
如果必须有证书,那么下面方法也不可用...
下面代码可以绕过HTTPS的证书校验:
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
1.在创建httpClient时用以下代码
每个请求中创建httpClient
CloseableHttpClient httpClient = createHttpsClient();
再调用GET或POST方法就可以绕过证书了。
public static CloseableHttpClient createHttpsClient() throws KeyStoreException, NoSuchAlgorithmException,KeyManagementException {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
//4.3版本之前用这个
//SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(
//builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
//4.3版本之后用这个
SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(builder.build(),
new String[] {"TLSv1"}, null,new NoopHostnameVerifier());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.
<ConnectionSocketFactory> create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslcsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslcsf)
.setConnectionManager(cm)
.build();
return httpClient;
};
2.创建Httpclient写成一个方法,例子:
每个请求中创建httpClient
CloseableHttpClient httpClient = createHttpsClient();
public static CloseableHttpClient createHttpsClient() throws NoSuchAlgorithmException, KeyManagementException {
X509TrustManager x509mgr = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509mgr}, null);
//4.3版本之前用这个
//SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslContext,
//SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
//4.3版本之后用这个
SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslContext,
new String[] {"TLSv1"}, null,new NoopHostnameVerifier());
return HttpClients.custom()
.setSSLSocketFactory(sslcsf)
.setDefaultRequestConfig(
RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setCookieSpec(String.valueOf(CookiePolicy.ACCEPT_ALL))
.build()).build();
}
参考:
java - Ignoring SSL certificate in Apache HttpClient 4.3 - Stack Overflow
https://blog.csdn.net/dietime1943/article/details/86679452#t3
https://blog.csdn.net/dietime1943/article/details/86705539
https://www.jianshu.com/p/7aabd65c44c2