Java Apache Http报错信息

在本地项目用ApacheHttp请求demo的时候报错:

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:456)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:323)
	at sun.security.validator.Validator.validate(Validator.java:271)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:315)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:223)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
	at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
	... 25 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:451)
	... 31 common frames omitted
Exception in thread "main" java.lang.RuntimeException: error

Java Apache Http实例代码


import com.alibaba.fastjson.JSONObject;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Map;


public enum HttpUtilDemo {
    ;
    private static final Logger logger = LoggerFactory.getLogger(HttpUtilDemo.class);

    /**
     * setConnectTimeout: 从客户端到url建立连接的超时时间
     */
    private static final int CONNECT_TIMEOUT = 30 * 1000;

    /**
     * setSocketTimeout: 连接上一个url后,获取response的返回等待时间
     */
    private static final int SOCKET_TIMEOUT = 3600 * 1000;

    public static JSONObject postHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setCookieSpec(CookieSpecs.DEFAULT)
                .build();

        CookieStore cookieStore = new BasicCookieStore();
        try (CloseableHttpClient httpClient = HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setDefaultCookieStore(cookieStore)
                .build()) {
            HttpPost post = new HttpPost(URL);
            // UTF-8 解决中文乱码
            StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
            post.addHeader("content-type", "application/json; charset=UTF-8");
            post.addHeader("Accept", "application/json");
            post.addHeader("Accept-Encoding", "UTF-8");
            post.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");

            if (!CollectionUtils.isEmpty(headerMap)) {
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    post.addHeader(entry.getKey(), entry.getValue());
                }
            }
            post.setEntity(params);

            // 发送 post 请求
            HttpResponse response = httpClient.execute(post);
            if (response == null) {
                throw new RuntimeException("response is null");
            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                InputStream in = response.getEntity().getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String lines;
                StringBuilder responseMsg = new StringBuilder("");
                while ((lines = reader.readLine()) != null) {
                    lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
                    responseMsg.append(lines);
                }
                reader.close();
                in.close();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", responseMsg.toString());
                // save header
                for (String name : headerName) {
                    jsonObject.put(name, response.getHeaders(name));
                }
                return jsonObject;
            } else {
                throw new RuntimeException("response status is not 200");
            }
        } catch (Exception ex) {
            logger.error("", ex);
            throw new RuntimeException("error");
        }
    }
}

问题代码片段

这里的代码有问题,需要开启绕过SSL的认证。

新增绕过https(SSL)认证

    /**
     * 绕过https证书校验
     */
    public static HttpClientBuilder createSSLClientDefaultBuilder() {
        HttpClientBuilder httpClientBuilder = null;
        try {
            SSLContextBuilder builder = new SSLContextBuilder();
            // 实现该接口,证书受信任的X509证书校验为true
            builder.loadTrustMaterial(null, (chain, authType) -> true);
            // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
            //  HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
            httpClientBuilder = HttpClients.custom().setSSLSocketFactory(socketFactory);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("系统异常");
        }
        return httpClientBuilder;
    }

Http工具修改后代码参考:


public enum HttpUtil {
    ;
    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * setConnectTimeout: 从客户端到url建立连接的超时时间
     */
    private static final int CONNECT_TIMEOUT = 30 * 1000;

    /**
     * setSocketTimeout: 连接上一个url后,获取response的返回等待时间
     */
    private static final int SOCKET_TIMEOUT = 3600 * 1000;

    public static JSONObject postHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setCookieSpec(CookieSpecs.DEFAULT)
                .build();

        CookieStore cookieStore = new BasicCookieStore();
        // 默认是 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        try (CloseableHttpClient httpClient = createSSLClientDefaultBuilder()
                .setDefaultRequestConfig(requestConfig)
                .setDefaultCookieStore(cookieStore)
                .build()) {
            HttpPost post = new HttpPost(URL);
            // UTF-8 解决中文乱码
            StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
            post.addHeader("content-type", "application/json; charset=UTF-8");
            post.addHeader("Accept", "application/json");
            post.addHeader("Accept-Encoding", "UTF-8");
            post.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");

            if (!CollectionUtils.isEmpty(headerMap)) {
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    post.addHeader(entry.getKey(), entry.getValue());
                }
            }
            post.setEntity(params);

            // 发送 post 请求
            HttpResponse response = httpClient.execute(post);
            if (response == null) {
                throw new RuntimeException("response is null");
            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                InputStream in = response.getEntity().getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String lines;
                StringBuilder responseMsg = new StringBuilder("");
                while ((lines = reader.readLine()) != null) {
                    lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
                    responseMsg.append(lines);
                }
                reader.close();
                in.close();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", responseMsg.toString());
                // save header
                for (String name : headerName) {
                    jsonObject.put(name, response.getHeaders(name));
                }
                return jsonObject;
            } else {
                throw new RuntimeException("response status is not 200");
            }
        } catch (Exception ex) {
            logger.error("", ex);
            throw new RuntimeException("error");
        }
    }


    public static JSONObject getHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setCookieSpec(CookieSpecs.DEFAULT)
                .build();

        CookieStore cookieStore = new BasicCookieStore();
        try (CloseableHttpClient httpClient = createSSLClientDefaultBuilder()
                .setDefaultRequestConfig(requestConfig)
                .build()) {
            HttpGet httpGet = new HttpGet(URL);
            // UTF-8 解决中文乱码
            StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
            httpGet.addHeader("content-type", "application/json; charset=UTF-8");
            httpGet.addHeader("Accept", "application/json");
            httpGet.addHeader("Accept-Encoding", "UTF-8");
            httpGet.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");

            if (!CollectionUtils.isEmpty(headerMap)) {
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 发送 httpGet 请求
            HttpResponse response = httpClient.execute(httpGet);
            if (response == null) {
                throw new RuntimeException("response is null");
            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                InputStream in = response.getEntity().getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String lines;
                StringBuilder responseMsg = new StringBuilder("");
                while ((lines = reader.readLine()) != null) {
                    lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
                    responseMsg.append(lines);
                }
                reader.close();
                in.close();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", responseMsg.toString());
                // save header
                for (String name : headerName) {
                    jsonObject.put(name, response.getHeaders(name));
                }
                return jsonObject;
            } else {
                throw new RuntimeException("response status is not 200");
            }
        } catch (Exception ex) {
            logger.error("", ex);
            throw new RuntimeException("error");
        }
    }


    /**
     * 绕过https证书校验
     */
    public static HttpClientBuilder createSSLClientDefaultBuilder() {
        HttpClientBuilder httpClientBuilder = null;
        try {
            SSLContextBuilder builder = new SSLContextBuilder();
            // 实现该接口,证书受信任的X509证书校验为true
            builder.loadTrustMaterial(null, (chain, authType) -> true);
            // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
            //  HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
            httpClientBuilder = HttpClients.custom().setSSLSocketFactory(socketFactory);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("系统异常");
        }
        return httpClientBuilder;
    }
}

请求示例

@Slf4j
public class RunTestDemo {
    @SneakyThrows
    public static void main(String[] args) {
        // 先登录获取token
        String url = "https://login.xxxx/login";
        JSONObject request = new JSONObject();
        request.put("password", "xxx");

        JSONObject object = HttpUtil.postHttpJsonData(url, request, null, "Set-Cookie");

        Map<String, String> headerMap = new HashMap<>();
        Header[] headers = (Header[]) object.get("Set-Cookie");
        headerMap.put("Cookie", headers[0].getValue());

        // 请求目标https
        String url2 = "https://xxxxxxx";
        JSONObject request2 = new JSONObject();
        request2.put("password", "xxxx");
        headerMap.put("requested", "xxxxx");
        JSONObject object2 = HttpUtil.postHttpJsonData(url2, request2, headerMap);
        log.info(object2.toJSONString());
    }
}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐