在https请求出现的SSL证书验证问题,异常信息如下:
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
在原始的代码中,我用HttpClient 创建客户端连接,在请求的时候出现SSLHandshakeException问题。
public class HttpClientUtil { public static String sendSSL(String url, String body, String contentType) throws Exception { // 创建SSLClient连接客户端 // CloseableHttpClient client = SSLClient.createSSLClient(); HttpClient client = HttpClientBuilder.create().build(); // 创建url的post请求对象 HttpPost post = new HttpPost(url); HttpEntity entity = new StringEntity(body, "utf-8"); // 将请求信息装载到post的entity中 post.setEntity(entity); if (contentType == null || "".equals(contentType)) { contentType = "text/html"; } post.setHeader("Content-Type", contentType); // 请求url获取响应 HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() == 200) { String resEntityStr = EntityUtils.toString(response.getEntity(), "UTF-8"); // client.close(); return resEntityStr; } else if (response.getStatusLine().getStatusCode() == 404) { //client.close(); throw new Exception("Exception has occurred."); } else { // client.close(); throw new Exception(); } } }
网上找了很多的帖子,也都试了方法,都是未见效,这里我自己写了一个工具类来信任所有证书。
(1)我用 CloseableHttpClient代替HttpClient 创建客户端连接,
CloseableHttpClient client = SSLClient.createSSLClient();
(2)在SSLClient 工具类中创建信任所有证书的连接,代码如下:
public class SSLClient { public static CloseableHttpClient createSSLClient() { SSLContext sslContext = null; try { sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { // 通过所有证书 return true; } }).build(); SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { // 不验证hostname return true; } }); // 如果异常了,创建普通的client return HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } return HttpClients.createDefault(); } }