Java代码解决Https请求出现的SSL证书验证问题

时间:2024-04-09 17:57:21

在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();
        // 创建urlpost请求对象
        HttpPost post = new HttpPost(url);
        HttpEntity entity = new StringEntity(body, "utf-8");
        // 将请求信息装载到postentity
        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();

Java代码解决Https请求出现的SSL证书验证问题
(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();
    }
}

Java代码解决Https请求出现的SSL证书验证问题