java HttpURLConnection 下载文件异常 301

  • Post author:
  • Post category:java


异常关键词:

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

下载代码

public static void main(String[] args) {
        HttpURLConnection connection = null;
        try {
            String url2 = "http://www.***.com/4f913bb5927_3864.pdf";
            URL url = new URL(url2);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            //设置超时间为3秒
            conn.setConnectTimeout(3*1000);

            //得到输入流
            InputStream inputStream = conn.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);

            //文件保存位置
            File saveDir = new File("K:\\home\\q\\");
            if(!saveDir.exists()){
                saveDir.mkdir();
            }
            String fileName = "123.pdf";
            File file = new File(saveDir+File.separator+fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if(fos!=null){
                fos.close();
            }
            if(inputStream!=null){
                inputStream.close();
            }

            System.out.println("info:"+url+" download success");

        } catch (Exception e) {
            System.out.println(e);
        }finally {
            if (null != connection) {
                connection.disconnect();
            }
        }

    }

保存的文件打不开,通过byte数据可以看到301了。

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

通过 conn.getHeaderFields()  发现url重定向到了 https请求,

进行重定向后的url获取:

String newUrl = "";
            if(conn.getHeaderFields().keySet().contains("Location")){
                newUrl = conn.getHeaderFields().get("Location").get(0);
            }
            url = new URL(newUrl);
            HttpURLConnection conn2 = (HttpURLConnection)url.openConnection();
            //设置超时间为3秒
            conn2.setConnectTimeout(3*1000);

执行报错:

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

解决SSL问题,修改为https,并忽略验证,否则会报错

            url = new URL(newUrl);
            HttpsURLConnection conn2 = (HttpsURLConnection)url.openConnection();
            //设置超时间为3秒
            conn2.setConnectTimeout(3*1000);
            conn2.setHostnameVerifier(DO_NOT_VERIFY);

这时候,报证书问题了:

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

最后解决:

   /**
     * 从输入流中获取字节数组
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static  byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }


    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    };

    public static void main(String[] args) {
        HttpURLConnection connection = null;
        try {
            String url2 = "http://wechaapi.xmskygzc.com/data/datafile/onlineService/signFile/2022/03/07/4be5418407e24209a0ac24f913bb5927_3864.pdf";
            URL url = new URL(url2);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();

            String newUrl = "";
            if(conn.getHeaderFields().keySet().contains("Location")){
                newUrl = conn.getHeaderFields().get("Location").get(0);
            }
            url = new URL(newUrl);
            HttpsURLConnection conn2 = (HttpsURLConnection)url.openConnection();
            //设置超时间为3秒
            conn2.setConnectTimeout(3*1000);
            conn2.setHostnameVerifier(DO_NOT_VERIFY);

            //得到输入流
            InputStream inputStream = conn2.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);

            //文件保存位置
            File saveDir = new File("K:\\home\\q\\");
            if(!saveDir.exists()){
                saveDir.mkdir();
            }
            String fileName = "123.pdf";
            File file = new File(saveDir+File.separator+fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if(fos!=null){
                fos.close();
            }
            if(inputStream!=null){
                inputStream.close();
            }

            System.out.println("info:"+url+" download success");

        } catch (Exception e) {
            System.out.println(e);
        }finally {
            if (null != connection) {
                connection.disconnect();
            }
        }

    }

    public static void main2(String[] args) {
        HttpURLConnection connection = null;
        try {
            String url2 = "http://www.***.com/e5418407e29a0ac24f913bb5927_3864.pdf";
            URL url = new URL(url2);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();

            String newUrl = "";
            if(conn.getHeaderFields().keySet().contains("Location")){
                newUrl = conn.getHeaderFields().get("Location").get(0);
            }


            url = new URL(newUrl);
            ignoreSsl();
            HttpsURLConnection conn2 = (HttpsURLConnection)url.openConnection();
            //设置超时间为3秒
            conn2.setConnectTimeout(3*1000);
            conn2.setHostnameVerifier(DO_NOT_VERIFY);

            //得到输入流
            InputStream inputStream = conn2.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);

            //文件保存位置
            File saveDir = new File("K:\\home\\q\\");
            if(!saveDir.exists()){
                saveDir.mkdir();
            }
            String fileName = "123.pdf";
            File file = new File(saveDir+File.separator+fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if(fos!=null){
                fos.close();
            }
            if(inputStream!=null){
                inputStream.close();
            }

            System.out.println("info:"+url+" download success");

        } catch (Exception e) {
            System.out.println(e);
        }finally {
            if (null != connection) {
                connection.disconnect();
            }
        }

    }

    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }
    static class miTM implements TrustManager,X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }
        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }
        public void checkServerTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
        public void checkClientTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
    }
    /**
     * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
     * @throws Exception
     */
    public static void ignoreSsl() throws Exception{
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }



版权声明:本文为dandanforgetlove原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。