[已解决]java-sun.security.validator.ValidatorException: PKIX path building failed

找了好多文章,终于找到个解决办法!

报错详情内容

[已解决]java-sun.security.validator.ValidatorException: PKIX path building failed_第1张图片

解决办法

第一种(适用于本人解决办法):

httpclient-4.5.jar 定时发送http包,忽然有一天报错,http证书变更引起的。

之前的代码

try {

            CloseableHttpClient httpClient = buildDefaultHttpClient();
            String url = domain.getUrl();
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("User-Agent", NetUtil.INSPECTOR_USER_AGENT);
            httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            httpGet.addHeader("Accept-Encoding", "gzip, deflate");
            httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.9");

            CloseableHttpResponse resp = httpClient.execute(httpGet);

            String responseBody = EntityUtils.toString(resp.getEntity(), "utf-8");

            respEnd = DateUtil.toEpochMilliseconds(LocalDateTime.now());

            len = responseBody.length();

            logger.info("http报文响应正文长度:{}B", len);

            String extractedTitle = NetUtil.extractTitle(responseBody);

            return builder.withRespEnd(respEnd).withRespLen(len)
                    .withHttpStatus((short) resp.getStatusLine().getStatusCode())
                    .withRetrieveTitle(extractedTitle)
                    .withTitleMatched(StringUtils.equals(domain.getTitle(), extractedTitle))
                    .build();


        } catch (IOException e) {
}

之后的代码

try {

            CloseableHttpClient httpClient = buildDefaultHttpClientTrustSSL();//信任证书

            String url = domain.getUrl();
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("User-Agent", NetUtil.INSPECTOR_USER_AGENT);
            httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            httpGet.addHeader("Accept-Encoding", "gzip, deflate");
            httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.9");

            CloseableHttpResponse resp = httpClient.execute(httpGet);

            String responseBody = EntityUtils.toString(resp.getEntity(), "utf-8");

            respEnd = DateUtil.toEpochMilliseconds(LocalDateTime.now());

            len = responseBody.length();

            logger.info("http报文响应正文长度:{}B", len);

            String extractedTitle = NetUtil.extractTitle(responseBody);

            return builder.withRespEnd(respEnd).withRespLen(len)
                    .withHttpStatus((short) resp.getStatusLine().getStatusCode())
                    .withRetrieveTitle(extractedTitle)
                    .withTitleMatched(StringUtils.equals(domain.getTitle(), extractedTitle))
                    .build();


        } catch (IOException e) {
}
/**
     * 信任SSL证书
     * @return
     */
    public static CloseableHttpClient buildDefaultHttpClientTrustSSL()
    {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        RequestConfig config = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setContentCompressionEnabled(true)
                .build();
        return HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
    }

 public static CloseableHttpClient buildDefaultHttpClient()
    {
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setContentCompressionEnabled(true)
                .setStaleConnectionCheckEnabled(true)
                .build();

        return HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
    }

例如:

我原来创建 httpClient 是这么写的:
 

CloseableHttpClient httpClient= HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()).build();

改之后:
 

 CloseableHttpClient httpClient= buildDefaultHttpClientTrustSSL();
 /**
     * 信任SSL证书
     * @return
     */
    public static CloseableHttpClient buildDefaultHttpClientTrustSSL()
    {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        RequestConfig config = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000)
                .setContentCompressionEnabled(true)
                .setCookieSpec(CookieSpecs.STANDARD)
                .build();
//        return HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
        return HttpClients.custom().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
    }

第二种:手动添加证书

在要访问的https网站,F12,如图:

[已解决]java-sun.security.validator.ValidatorException: PKIX path building failed_第2张图片

View certificate(蓝色部分)-- 导出证书 

导入证书:

keytool -import -v -trustcacerts -alias taobao -file taobao.cer -storepass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts


解释说明:

1、taobao 是可以自己修改的名称,  taobao.cer 是导出的证书,同样,这里的证书名字也是随便取的,但前提是保证将%JAVA_HOME%/jre/lib/security目录的cacerts文件内之前没有导入同名证书,就是要保证你将要导入的证书名称唯一性。
2、changeit 是密码, java默认的。 
3、keytool是jdk中bin目录的一个exe文件,是jdk默认自带的,在我电脑的目录是:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/bin/keytool.exe
4、%JAVA_HOME%/jre/lib/security/cacerts 这个路径中%JAVA_HOME%/jre/lib/security/是路径,cacerts是文件(即将要把证书导入到其中的文件)。当然要确保你已经配置过java_home环境变量,我的java_home环境变量为:/usr/lib/jvm/java-1.8.0-openjdk-amd64
5、其他保持不变。
6、如果提示:"是否信任此证书? [否]:"  ,那么请输入"y"。
 

其实这个方法也是有效的

你可能感兴趣的:(java)