HttpClient跳过https证书认证

时间:2025-02-12 20:40:56

起因是因为报了一个错

: : PKIX path building failed: : unable to find valid certification path to requested target
	at (:192)
	at (:1949)
	at (:302)
	at (:296)
	at (:1509)
	at (:216)
	at (:979)
	at .process_record(:914)
	at (:1062)
	at (:1375)
	at (:1403)
	at (:1387)
	at (:396)
	at (:355)
	at (:142)
	at (:373)
	at (:394)
	at (:237)
	at (:185)
	at (:89)
	at (:110)
	at (:185)
	at (:83)
	at (:108)
	at .(:48)
Caused by: : PKIX path building failed: : unable to find valid certification path to requested target
	at (:387)
	at (:292)
	at (:260)
	at .(:324)
	at .(:229)
	at .(:124)
	at (:1491)
	... 20 more
Caused by: : unable to find valid certification path to requested target
	at (:141)
	at (:126)
	at (:280)
	at (:382)
	... 26 more

研究了一下,是因为我们进行https连接时,需要证书进行认证,我们在java代码中可以通过跳过认证来避免这种情况

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Demo02 {

    public static void main(String[] args) {
        HttpPost httpPost = new HttpPost("XXXXXXXXX");
        // 请求头
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Connection", "keep-alive");
        httpPost.addHeader("Content-Type", "application/json");


        RequestConfig config = RequestConfig
                .custom()
                .setConnectTimeout(100)
                .setSocketTimeout(80)
                .build();

        //这部分代码是重点
        SSLContext sslContext = getSSLContext();
        Registry<ConnectionSocketFactory> socketFactoryRegistry =
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", PlainConnectionSocketFactory.INSTANCE)
                        .register("https", new SSLConnectionSocketFactory(sslContext)).build();
        PoolingHttpClientConnectionManager mananger = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        mananger.setMaxTotal(100);
        mananger.setDefaultMaxPerRoute(20);

        CloseableHttpClient client = HttpClients
                .custom()
                .setDefaultRequestConfig(config)
                .setConnectionManager(mananger)
                .build();

        try {
            client.execute(httpPost);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static SSLContext getSSLContext() {
        try {
            // 这里可以填两种值 TLS和LLS , 具体差别可以自行搜索
            SSLContext sc = SSLContext.getInstance("TLS");
            // 构建新对象
            X509TrustManager manager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }

                // 这里返回Null
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sc.init(null, new TrustManager[]{manager}, null);
            return sc;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}