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
相关产品推荐
相关产品推荐

