• Java向指定URL发送请求出现net.ssl.SSLHandshakeException: PKIX path building failed异常


    1 Java在做向指定 Url 发送 get 请求时报错

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

     

    2 原因分析

    1. 网上搜的:google发现stackoverflow上不少人反应,twitter和新浪微博的api也会报这个异常,不少人反映客户端需要导入证书,其实大可不必,如果要导证书的话,用户不得哭了。。

    2. 我是做WebSSO单点登录,要调到统一授权页面获取Xml信息,获取结果的时候报的错。

    3. 用的第一种方式发送get请求,报这个错误!!!

    /**
         * 向指定的地址发送get请求
         *
         * @param url
         * @return
         */
        public static String getRequest(String url) {
            try {
                URL urlObj = new URL(url);
                URLConnection connection = urlObj.openConnection();
                InputStream is = connection.getInputStream();
                byte[] b = new byte[1024];
                int len;
                StringBuilder sb = new StringBuilder();
                while ((len = is.read(b)) != -1) {
                    sb.append(new String(b, 0, len));
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    3. 换一种发送get请求,还是报这个错误!!!

    添加项目依赖

    <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.13</version>
    </dependency>

    测试方法

    import java.io.IOException;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    public class SendGetRequest {
    
        public static void main(String[] args) throws IOException {
            // 向url发送GET请求
            String url = "";
            CloseableHttpClient httpClient = HttpClients.createDefault();
            try {
                HttpGet httpGet = new HttpGet(url);
                CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
                try {
                    System.out.println(httpResponse.getStatusLine());
                    HttpEntity httpEntity = httpResponse.getEntity();
                    // 添加处理返回数据的代码
                    // 例如将返回的数据转换为字符串并输出
                    System.out.println(EntityUtils.toString(httpEntity));
                    EntityUtils.consume(httpEntity);
                } finally {
                    httpResponse.close();
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                httpClient.close();
            }
        }
    }

    3 解决方法

    3.1 我的可能是单点登录统一授权的url有限制出现的问题,朋友们可以试下上面两种请求方式

    3.2 手动导入证书到本地证书库(不推荐)

    可以参考 导入证书

    3.3 调整发生请求的代码,信任所有证书

    1. trustAllHosts 该方法放任所以请求,不在校验时候有证书

       /**
         * Trust every server - dont check for any certificate
         */
        private static void trustAllHosts() {
            final String TAG = "trustAllHosts";
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
    
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
            }};
            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    2. https.setHostnameVerifier(DO_NOT_VERIFY); 表示信任所有的证书

    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

    3. 发送请求的代码

    /**
         * 向指定的地址发送get请求忽略证书
         *
         * @param httpUrl
         * @return
         */
        public static String httpGet(String httpUrl) {
            BufferedReader input = null;
            StringBuilder sb = null;
            URL url = null;
            HttpURLConnection con = null;
            try {
                url = new URL(httpUrl);
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                if (url.getProtocol().toLowerCase().equals("https")) {
                    https.setHostnameVerifier(DO_NOT_VERIFY);
                    con = https;
                } else {
                    con = (HttpURLConnection) url.openConnection();
                }
                input = new BufferedReader(new InputStreamReader(con.getInputStream()));
                sb = new StringBuilder();
                String s;
                while ((s = input.readLine()) != null) {
                    sb.append(s).append("\n");
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            } finally {
                // close buffered
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                // disconnecting releases the resources held by a connection so they may be closed or reused
                if (con != null) {
                    con.disconnect();
                }
            }
            return sb == null ? null : sb.toString();
        }
    
        final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
    
        /**
         * Trust every server - dont check for any certificate
         */
        private static void trustAllHosts() {
            final String TAG = "trustAllHosts";
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
    
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
            }};
            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    4. 完整的工具类代码

    package http;
    
    import javax.net.ssl.*;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    /**
     * 向url发送请求
     */
    public class SendRequestUtil {
    
        /**
         * 向指定的地址发送get请求
         *
         * @param url
         * @return
         */
        public static String getRequest(String url) {
            try {
                URL urlObj = new URL(url);
                URLConnection connection = urlObj.openConnection();
                InputStream is = connection.getInputStream();
                byte[] b = new byte[1024];
                int len;
                StringBuilder sb = new StringBuilder();
                while ((len = is.read(b)) != -1) {
                    sb.append(new String(b, 0, len));
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 向指定的地址发送post请求
         *
         * @param url  url
         * @param data 参数
         * @return
         */
        public static String postRequest(String url, String data) {
            try {
                URL urlObj = new URL(url);
                URLConnection connection = urlObj.openConnection();
                // 发送数据,把状态设置为可发送
                connection.setDoOutput(true);
                // 获取输出流
                OutputStream os = connection.getOutputStream();
                os.write(data.getBytes());
                os.close();
                InputStream is = connection.getInputStream();
                byte[] b = new byte[1024];
                int len;
                StringBuilder sb = new StringBuilder();
                while ((len = is.read(b)) != -1) {
                    sb.append(new String(b, 0, len));
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 向指定的地址发送get请求忽略证书
         *
         * @param httpUrl
         * @return
         */
        public static String httpGet(String httpUrl) {
            BufferedReader input = null;
            StringBuilder sb = null;
            URL url = null;
            HttpURLConnection con = null;
            try {
                url = new URL(httpUrl);
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                if (url.getProtocol().toLowerCase().equals("https")) {
                    https.setHostnameVerifier(DO_NOT_VERIFY);
                    con = https;
                } else {
                    con = (HttpURLConnection) url.openConnection();
                }
                input = new BufferedReader(new InputStreamReader(con.getInputStream()));
                sb = new StringBuilder();
                String s;
                while ((s = input.readLine()) != null) {
                    sb.append(s).append("\n");
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            } finally {
                // close buffered
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                // disconnecting releases the resources held by a connection so they may be closed or reused
                if (con != null) {
                    con.disconnect();
                }
            }
            return sb == null ? null : sb.toString();
        }
    
        final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
    
        /**
         * Trust every server - dont check for any certificate
         */
        private static void trustAllHosts() {
            final String TAG = "trustAllHosts";
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
    
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
            }};
            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    SendRequestUtil

     

  • 相关阅读:
    过滤的特殊字符
    iOS中正则表达式的基本使用方法
    sqlite3特殊的字符转义
    tableView的设置
    IOS中设置cell的背景view和选中时的背景view 、设置cell最右边的指示器(比如箭头文本标签)
    IOS中(类似于进度条哪种效果)MBProgressHUD的使用
    ISO中AFN的使用步骤
    IOS中用UIFont返回字体的行高、动态改变tableView中Cell的高度
    iso中第三方框架SDWebImage的使用步骤
    iso中自动伸缩属性
  • 原文地址:https://www.cnblogs.com/liyhbk/p/15986458.html
Copyright © 2020-2023  润新知