报错信息
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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
这个错误通常表示 SSL 握手失败,原因是由于证书验证问题导致。在 SSL 握手期间,客户端会验证服务器端的证书是否可信。如果证书无法验证或者未找到与之匹配的有效证书路径,就会抛出该异常。
出现这个异常的原因可能有以下几种情况:
- 服务器端的 SSL 证书没有被公认的证书颁发机构(CA)所信任。
- 客户端缺少根证书或中间证书,导致无法建立有效证书路径。
- HTTPS 请求被代理服务器拦截,产生了证书问题。
我的解决方法
在使用 Jsoup 进行 HTTP 请求时禁用 SSL 证书验证,可以通过以下步骤实现:
- 创建一个自定义的
TrustManager
类,用于忽略对证书的验证,示例代码如下: -
package org.jeecg.modules.pachon.HtmlPachon.entity; import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class TrustAllCertManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }
- 在发送请求之前,通过
TrustAllCertManager
类创建一个自定义的SSLContext
对象,并将其应用于HttpsURLConnection
类,示例代码如下 -
public void rawDataHomePage() { // 创建自定义 TrustManager TrustManager[] trustManagers = new TrustManager[]{new TrustAllCertManager()}; // 获取默认的 SSLContext SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustManagers, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); } // 应用自定义的 SSLContext HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); try { Connection.Response response = Jsoup.connect("http://data.stats.gov.cn/easyquery.htm?m=QueryData&dbcode=fsyd&rowcode=zb&colcode=sj&wds=%5B%7B%22wdcode%22%3A%22reg%22%2C%22valuecode%22%3A%22110000%22%7D%5D&dfwds=%5B%7B%22wdcode%22%3A%22zb%22%2C%22valuecode%22%3A%22A030102%22%7D%5D&k1=1692174996701&h=1") .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54") .ignoreContentType(true) .execute(); String body = response.body(); JSONObject jsonObject = JSONObject.parseObject(body); } catch (IOException e) { e.printStackTrace(); }
通过上述方法,你可以在使用 Jsoup 发送请求时禁用 SSL 证书验证。请注意,在禁用证书验证时,存在安全风险,请仅在开发和测试环境下使用,并确保在生产环境中启用证书验证。
希望这些信息能够帮助到你!如果还有其他问题,请随时提问。