【踩坑系列】使用httpclient調(diào)用第三方接口返回javax.net.ssl.SSLHandshakeException異常
2025-03-27 10:57 申城異鄉(xiāng)人 閱讀(238) 評論(0) 收藏 舉報1. 踩坑經(jīng)歷
最近做了個需求,需要調(diào)用第三方接口獲取數(shù)據(jù),在聯(lián)調(diào)時一直失敗,代碼拋出javax.net.ssl.SSLHandshakeException異常,
具體錯誤信息如下所示:
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
2.原因分析
因為調(diào)用第三方接口的代碼是復用項目中原有的工具類(基于httpclient封裝),所以在確認完傳參沒問題后,第一時間排除了編碼問題。
然后開始懷疑第三方提供的接口地址(因為竟然是IP+端口訪問),在和第三方確認沒有域名訪問后,在瀏覽器里輸入第三方的接口地址,發(fā)現(xiàn)證書有問題:

又使用Postman調(diào)用第三方接口,也是失敗,提示自簽名證書:

通過以上分析,可以發(fā)現(xiàn)出現(xiàn)該問題的根本原因是Java客戶端不信任目標服務器的SSL證書,比如這個第三方使用的自簽名證書。
3.解決方案
解決方案一般有2種,第1種方案是將服務器證書導入Java信任庫,第2種方案是繞過SSL驗證,這里采用第2種方案。
首先,新建HttpClient工具類:
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
public class HttpClientUtils {
public static CloseableHttpClient createIgnoreCertClient() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}}, new java.security.SecureRandom());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}
}
然后將原來聲明httpClient的代碼改為如下所示:
CloseableHttpClient httpClient = HttpClientUtils.createIgnoreCertClient();
注意事項:
確保項目中引入了httpclient依賴:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
文章持續(xù)更新,歡迎關注微信公眾號「申城異鄉(xiāng)人」第一時間閱讀!
浙公網(wǎng)安備 33010602011771號