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

如何从响应的PDF八位字节/流字符串生成可正常打开的PDF文件?

解决RestTemplate获取PDF流后生成空白文件的问题

问题根源

你现在遇到的空白PDF问题,核心原因是把二进制的PDF流当成String来接收和处理了。PDF是二进制文件,里面包含大量非文本的字节序列,而String是基于字符编码(比如UTF-8)的容器,当你将二进制字节转成String时,那些无法被字符编码识别的字节会被替换或丢失,最终导致写入的文件损坏,打开自然是空白。

修复方案:直接处理二进制字节流

你需要修改RestTemplate的响应接收类型,避免用String中转,直接用byte[]或者Resource来接收二进制数据,这样就能完整保留PDF的原始字节信息。

方案1:用byte[]直接接收响应

这是最直接的方式,把响应体直接拿到字节数组,然后写入文件:

// 修改响应类型为byte[]
ResponseEntity<byte[]> response = restTemplate.exchange(downloadFileUrl, HttpMethod.GET, request, byte[].class, urlParams);
System.out.println(response.getStatusCode());

try (OutputStream out = new FileOutputStream("C:\\Users\\downloaded.pdf")) {
    // 直接写入原始字节数组,无需转码
    out.write(response.getBody());
} catch (IOException e) {
    e.printStackTrace();
}

方案2:用Resource处理流(更适合大文件)

如果PDF文件较大,用流的方式读写可以节省内存:

// 修改响应类型为Resource
ResponseEntity<Resource> response = restTemplate.exchange(downloadFileUrl, HttpMethod.GET, request, Resource.class, urlParams);
System.out.println(response.getStatusCode());

try (InputStream in = response.getBody().getInputStream();
     OutputStream out = new FileOutputStream("C:\\Users\\downloaded.pdf")) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    // 逐块读写,避免一次性加载大文件到内存
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}

额外注意:确保请求头正确

有时候接口需要你明确指定接受PDF格式的响应,否则可能返回错误的内容。你可以在请求中添加Accept头:

HttpHeaders headers = new HttpHeaders();
// 设置接受application/pdf类型的响应
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_PDF));
HttpEntity<String> request = new HttpEntity<>(headers);

这样调整后,生成的PDF文件应该就能正常打开了。

内容的提问来源于stack exchange,提问作者phalanndwa swethane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:46:55