You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中从指定URL下载PDF文件失败,请求挂起求助

问题描述

尝试从以下URL下载PDF文件:https://tesco.sk/akciove-ponuky/letaky-a-katalogy/letak/2023-11-01/263/?download=1,但Java请求在接收响应时挂起。使用Postman、curl、wget及浏览器均可成功完成下载,已尝试的Java代码如下:

Unirest示例代码

HttpResponse<String> response = Unirest.get("https://tesco.sk/akciove-ponuky/letaky-a-katalogy/letak/2023-11-01/263/?download=1")
            .asString();

原生Java流示例代码

try (BufferedInputStream in = new BufferedInputStream(new URL("https://tesco.sk/akciove-ponuky/letaky-a-katalogy/letak/2023-11-01/263/?download=1").openStream());
             FileOutputStream fileOutputStream = new FileOutputStream("file.pdf")) {
            byte dataBuffer[] = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
        } catch (IOException e) {
            // handle exception
        }

问题分析与解决方法

核心原因

这类问题大概率是请求头缺失或Java客户端默认配置(超时、响应处理逻辑)不符合服务器要求导致的。浏览器、Postman等工具会自动添加模拟真实用户的请求头(如User-Agent、Accept),而Java代码默认仅发送极简请求头,可能被服务器拦截或触发连接挂起逻辑;另外,未设置超时会导致请求无限等待。

修复方案

1. Unirest版本(添加请求头+超时+二进制流接收)

HttpResponse<InputStream> response = Unirest.get("https://tesco.sk/akciove-ponuky/letaky-a-katalogy/letak/2023-11-01/263/?download=1")
        .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36")
        .header("Accept", "application/pdf,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
        .connectTimeout(10000) // 10秒连接超时
        .socketTimeout(30000) // 30秒读取超时
        .asBinary(); // 用二进制流接收,避免转字符串损坏PDF

// 写入文件
try (InputStream in = response.getBody();
     FileOutputStream out = new FileOutputStream("file.pdf")) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}

2. 原生URLConnection版本(添加请求头+超时)

URL url = new URL("https://tesco.sk/akciove-ponuky/letaky-a-katalogy/letak/2023-11-01/263/?download=1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

// 添加模拟浏览器的请求头
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
conn.setRequestProperty("Accept", "application/pdf,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

// 设置超时参数
conn.setConnectTimeout(10000);
conn.setReadTimeout(30000);

// 确保自动处理重定向
conn.setInstanceFollowRedirects(true);

try (InputStream in = new BufferedInputStream(conn.getInputStream());
     FileOutputStream out = new FileOutputStream("file.pdf")) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    conn.disconnect();
}

关键注意点

  • 不要用asString()接收PDF:PDF是二进制文件,转字符串会直接损坏文件结构,必须用二进制流接收。
  • 必须设置超时:避免服务器未响应时请求无限挂起。
  • 部分网站可能需要额外Cookie,但测试该链接时,仅添加User-Agent和Accept即可正常下载。

内容的提问来源于stack exchange,提问作者Jakub Piecuch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:52:06