【问题标题】:Download xml.gz file with HttpsURLConnection使用 HttpsURLConnection 下载 xml.gz 文件
【发布时间】:2010-09-19 10:25:37
【问题描述】:

我正在尝试使用 java 中的 HttpsURLConnection 从远程服务器下载 xml.gz 文件,但我得到一个空响应。这是我的代码示例:

URL server = new URL("https://www.myurl.com/path/sample_file.xml.gz");
HttpsURLConnection connection = (HttpsURLConnection)server.openConnection();
connection.connect();

当我尝试从连接中获取 InputStream 时,它是空的。 (如果我尝试 connection.getInputStream().read() 我得到-1)我期望的文件大约是 50MB。

为了测试我的理智,我还尝试在浏览器中输入完全相同的 url,它确实返回了我需要的文件。我错过了什么吗?我是否必须在连接中设置某种参数?非常感谢任何帮助/指导。

【问题讨论】:

    标签: java ssl https


    【解决方案1】:

    是否记录了任何异常?该网站提供的是自签名 SSL 证书,还是未经 CA 签名的证书?它可能在您的浏览器中运行良好(浏览器可能已被告知接受来自该域的自签名证书)而不是在您的代码中运行良好的原因有多种。

    使用curlwget获取网址的结果是什么?

    InputStream 为空/ InputStream.read() == -1 结果的事实意味着流中没有可读取的内容,这意味着甚至无法正确设置流。

    更新See this page 了解如何处理连接代码中的无效/自签名证书。或者,如果站点提供了一个证书但它是无效的,你可以将它导入到服务器的密钥库中,告诉 Java 信任该证书。 See this page for more info.

    【讨论】:

    • 提供文件的第三方最初告诉我使用 curl 如下: curl --location -C - --digest -k myurl.com/path/sample_file.xml.gz -o sample_file.xml.gz 这很好用也!
    • 带有 curl 的 -k 开关表示“允许在没有证书的情况下连接到 SSL 站点”,所以我认为可以安全地假设该站点没有提供有效的证书。你必须更新你的代码来解决这个问题
    • curl 命令可以在没有 -k 开关的情况下工作。我猜这意味着证书是有效的。
    【解决方案2】:
    1. 验证 response code 是 200
    2. 检查 connection.contentType 以验证内容类型是否被识别
    3. 您可能需要为 GZ mime 类型添加一个 Content-Handler,我想不起来了。

    在将响应代码描述为 3xx 的注释之后,

    1. 设置'connection.setFollowRedirects(true)'

    应该修复它。

    【讨论】:

    • 响应码为 302,表示“请求的数据实际上位于不同的 URL 下”。我想知道这是否是我的问题......我想这就是为什么提供者告诉我在使用 curl 下载文件时使用“-location”参数的原因。有没有办法解决这个问题?
    • 'connection.setFollowRedirects(true)' 应该这样做。
    • followRedirects 属性默认设置为 true,我能够看到重定向的 url。但是,从您的原始答案中,我注意到当我执行 connection.getContentType() 时,会返回 null。这是否意味着我必须为 mime 类型“application/x-gzip”创建一个 ContentHandler[Factory]?
    【解决方案3】:

    原来下载不起作用,因为远程服务器将我重定向到一个新的 url 来下载文件。即使设置了 connection.setFollowRedirects(true),我仍然必须手动为重定向的 URL 设置新连接,如下所示:

    if (connection.getResponseCode() == 302 && connection.getHeaderField("location") != null){
                URL server2 = new URL(connection.getHeaderField("location"));
                HttpURLConnection connection2 = (HttpURLConnection)server2.openConnection();
                connection2.connect();
                InputStream in = connection2.getInputStream();
    }
    

    之后,我能够从输入流中检索文件。感谢大家的帮助!

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2010-12-20
    • 2016-01-06
    • 2018-04-08
    • 1970-01-01
    相关资源
    最近更新 更多