如何从响应的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
相关产品推荐
相关产品推荐

