在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(); } }