Spring Boot接口PDF下载失败问题排查求助
Spring Boot PDF下载接口问题排查与修复
你的Controller代码存在几个潜在问题,可能导致下载失败:
- 文件名未编码:直接拼接CPF作为文件名,若包含
.、-这类特殊字符,部分浏览器可能无法正确解析文件名,进而影响下载流程。 - InputStreamResource的局限性:ByteArrayInputStream包装成InputStreamResource后,Spring无法自动获取文件长度,浏览器无法确认文件大小,可能中断下载。
- 异常状态码错误:生成PDF失败属于服务端内部错误,返回
400 Bad Request不符合HTTP规范,应返回500 Internal Server Error。
修改后的代码:
@RestController @RequestMapping("/api/pdf") public class PdfController { private final PdfService pdfService; public PdfController(PdfService pdfService) { this.pdfService = pdfService; } @PostMapping("/generate") public ResponseEntity<ByteArrayResource> createPdf(@RequestBody PendenciasModel pendenciasModel) throws IOException { try { ByteArrayInputStream bis = pdfService.createPdf(pendenciasModel); byte[] pdfBytes = bis.readAllBytes(); ByteArrayResource resource = new ByteArrayResource(pdfBytes); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); // 按RFC规范编码文件名,兼容特殊字符 String encodedFilename = URLEncoder.encode(pendenciasModel.getClient().getCpf() + ".pdf", StandardCharsets.UTF_8); headers.setContentDisposition(ContentDisposition.attachment() .filename(encodedFilename, StandardCharsets.UTF_8) .build()); headers.setContentLength(pdfBytes.length); return ResponseEntity.ok() .headers(headers) .body(resource); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } }
额外检查项:
- 确认
pdfService.createPdf()返回的ByteArrayInputStream未被提前读取(若流指针已到末尾,响应内容为空)。 - 前端调用时需设置响应类型为
blob,避免框架默认将响应解析为JSON:// 以axios为例 axios.post('/api/pdf/generate', requestData, { responseType: 'blob' }) .then(res => { const url = window.URL.createObjectURL(new Blob([res.data])); const a = document.createElement('a'); a.href = url; a.download = res.headers['content-disposition'].split('filename=')[1]; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); a.remove(); });
内容的提问来源于stack exchange,提问作者Michel Lopes
相关产品推荐
相关产品推荐

