当前位置: 首页 > 面试题库 >

如何从JAVA中的HTTPS URL保存文件?

萧鹏云
2023-03-14
问题内容

我正在尝试使用outputstream从URL保存文件。该URL由https保护。所以当我尝试获取文件时出现以下错误

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
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at java.net.URL.openStream(Unknown Source) 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 60 more

假设我要从此URL打开文件

https://www.filepicker.io/api/file/KW9EJhYtS6y48Whm2S6D?signature=4098f262b9dba23e4766ce127353aaf4f37fde0fd726d164d944e031fd862c18&policy=eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=

所以我做类似的事情:

try{    
    URL URL = new URL('https://www.filepicker.io/api/file/KW9EJhYtS6y48Whm2S6D?signature=4098f262b9dba23e4766ce127353aaf4f37fde0fd726d164d944e031fd862c18&policy=eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=');
    String = path = "D://download/";
    InputStream ins = url.openStream();
    OutputStream ous = new FileOutputStream(path);
    final byte[] b = new byte[2048];
    int length;

        while ((length = inputStream.read(b)) != -1) {
               ous.write(b, 0, length);
         }

           ins.close();
           ous.close();
}

结果不会在专用选粉机上发生任何事情,因为会显示错误。如何从HTTPS网址获取文件?


问题答案:

HTTPS连接需要握手。即明确承认对方。服务器已经通过HTTPS证书标识了自己,但是您显然没有在信任存储区中使用此证书,并且您在Java代码中没有任何位置明确确认该标识,因此HttpsURLConnection(此处将在此处使用)拒绝继续HTTPS请求。

作为启动示例,您可以在类中使用以下代码来HttpsURLConnection接受所有SSL证书,而不管使用的是HTTPS URL。

static {
    final TrustManager[] trustAllCertificates = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null; // Not relevant.
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
        }
    };

    try {
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCertificates, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (GeneralSecurityException e) {
        throw new ExceptionInInitializerError(e);
    }
}

但是,如果您希望在每个证书的基础上进行更细粒度的控制,请根据其Javadoc相应地实现这些方法。

具体问题 无关 ,代码中还有第二个问题。您正在尝试将下载的文件保存为文件夹而不是文件。

String = path = "D://download/";
OutputStream ous = new FileOutputStream(path);

除了语法错误(很可能是在制定问题时粗心大意导致的语法错误(即直接编辑有问题的代码而不是实际复制粘贴工作代码)之外),这没有任何意义。您不应将文件夹指定为保存位置。您应该指定一个文件名。您可以根据需要从Content- Disposition标题中提取它,也可以使用来自动生成一个File#createTempFile()。例如

File file = File.createTempFile("test-", ".jpg", new File("D:/download/"));
Files.copy(url.openStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);

(如果您已经在使用Java 7,请使用Files#copy()代替该样板)



 类似资料:
  • 我使用java通过materiliazed视图将数据存储到Cassandra中,但我遇到了一个问题。问题是它不能将数据保存到Cassandra数据库。我得到了这个错误。 如果不存在sensorkeyspace.maxtable将物化视图重放为select sensor_id,湿度来自sensorkeyspace.sensortable,其中(湿度不为null)主键(sensor_id)异常位于线程

  • 问题内容: http://www.example.com/information.asp我需要获取一个在线文件(例如),并将其保存到目录中。我知道有几种方法可以逐行捕获和读取在线文件(URL),但是有没有一种方法可以使用Java下载和保存文件? 问题答案: 可以使用 Java NIO : 使用是可能不是一个简单的循环从源信道的读取和写入这个频道有效得多。许多操作系统可以直接将字节从源通道传输到文件

  • 有一个联机文件(如)我需要抓取并保存到目录中。我知道有几种方法来抓取和读取在线文件(URL),逐行,但有没有一种方法只是下载和保存文件使用Java?

  • 问题内容: 我有一个在docker-machine上运行的weblogic容器(正在使用docker toolbox在Windows 7上运行),并希望将日志从容器自动保存到Windows机器。 我知道我可以使用命令,但是,不是每次都将日志记录到Windows计算机上,而是有更好的方法将日志从容器保存到Windows计算机上的文件夹中吗? 问题答案: 请参阅“ Docker日志记录策略 ”,其中介

  • 问题内容: 我使用以下代码将汉字保存到.txt文件中,但是当我用写字板打开它时,我看不懂它。 我能做什么 ?我知道如果将汉字剪切并粘贴到写字板中,可以将其保存到.txt文件中。如何在Java中做到这一点? 问题答案: 这里有几个因素在起作用: 文本文件没有用于描述其编码的内在元数据(就尖括号税而言,XML受欢迎是有原因的) Windows的默认编码仍然是8位(或双字节)“ ANSI ”字符集,其值

  • 问题内容: 因此,我以前有很多.js文件曾经用于从命令行界面查询MongoDB,但现在我希望能够通过Java运行相同的查询(我正在使用Java来支持依赖于Web界面的Web查询中的信息)。如何使用Java驱动程序中的JavaScript查询并返回一些我可以使用的数据(最终的方法是将结果格式化为HTML,如果有帮助的话)。 问题答案: 如果您需要在构建期间执行js文件,则可以使用maven-mong