1.背景

一个下载文件的服务在A机器上可以正常下载,但是子啊B机器上下载保存,提示如下:

下载处理异常:请求接口异常:sun.security.validator.ValidatorException:
 PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
 unable to find valid certification path to requested target

通过报错信息,大概报错的含义是,发送请求时证书检查失败(过期)等错误,

解决办法是,在发送请求前,添加一个信任所有证书的请求对象(SSLContentext)

2.解决步骤

修改下载文件的get请求方法,修改前的下载方法是:

 /**
     * 发送一个get请求
     *
     * @param url     请求地址
     * @param params  名值对参数
     * @param charset 编码
     * @return
     */
    public static String get(String url, Map<String, String> params,
                             String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(
                        params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?"
                        + EntityUtils.toString(new UrlEncodedFormEntity(pairs,
                        charset));
            }

            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(10000).setConnectionRequestTimeout(10000)
                    .setSocketTimeout(10000).build();
            httpGet.setConfig(requestConfig);
            httpGet.setHeader("Accept", "application/json;charset=UTF-8");
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new ParamException("请求接口状态返回不是200:" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, charset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOGGER.error("请求接口异常:" + e.getMessage());
            throw new ParamException("请求接口异常:" + e.getMessage());
        }
    }

修改后的下载方法为:

 /**
     * 发送一个get请求
     *
     * @param url     请求地址
     * @param params  名值对参数
     * @param charset 编码
     * @return
     */
    public static String get2(String url, Map<String, String> params,
                              String charset) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(
                        params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?"
                        + EntityUtils.toString(new UrlEncodedFormEntity(pairs,
                        charset));
            }

            // 创建一个信任所有证书的SSLContext
            SSLContext sslContext = SSLContextBuilder.create()
                    .loadTrustMaterial(null, (certificateChain, authType) -> true)
                    .build();

            // 创建一个不验证主机名的SSLConnectionSocketFactory
            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

            // 创建CloseableHttpClient实例
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(csf)
                    .build();

            // 创建HttpGet请求l
            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(10000).setConnectionRequestTimeout(10000)
                    .setSocketTimeout(10000).build();
            httpGet.setConfig(requestConfig);
            httpGet.setHeader("Accept", "application/json;charset=UTF-8");
            // 发送请求并获取响应
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new ParamException("请求接口状态返回不是200:" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, charset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOGGER.error("请求接口异常:" + e.getMessage());
            throw new ParamException("请求接口异常:" + e.getMessage());
        }
    }

修改后发布到服务器上,2台机器都可以正常下载了!

3.完美

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐