Spring Boot相同下载代码无法触发浏览器下载PDF是什么原因?
从你给出的响应头对比可以看出,主项目的响应完全没有包含下载需要的Content-Disposition、Content-Type头,且Content-Length为0,说明你的返回结果被主项目中的全局处理逻辑拦截修改,或者接口逻辑没有正常执行完成,可按照以下步骤排查解决:
- 第一步:先确认请求是否能进入你的下载接口方法,可以在方法第一行加断点或者日志,验证请求是否被正确路由到该方法。如果没有进入,检查主项目的权限控制(如Spring Security规则)、接口路径匹配规则,排除路径被拦截、重定向的问题。
- 第二步:排查全局响应包装逻辑。绝大多数主项目会配置全局返回值处理器,将所有接口返回统一封装为固定格式的JSON结构,这会直接覆盖你返回的
ResponseEntity<Resource>资源对象,清空响应头和响应体。解决方法为自定义一个跳过包装的标记注解,在全局处理器中判断如果接口标注了该注解,就直接返回原始内容不做包装。 - 第三步:补充文件存在性校验和异常处理。你原有代码中如果读取文件抛出
MalformedURLException,只会打印堆栈,此时resource为null,返回的响应体为空,就会出现Content-Length: 0的情况。可以参考下方优化后的代码:
@GetMapping("/download") public ResponseEntity<Resource> downloadFileFromLocal() throws IOException { Path path = Paths.get(System.getProperty("user.home") + "/downloads/fileName.pdf"); // 校验文件是否存在 if (!Files.exists(path)) { return ResponseEntity.notFound().build(); } Resource resource = new UrlResource(path.toUri()); // 主动设置内容长度、标准下载类型、文件名编码避免乱码 return ResponseEntity.ok() .contentType(MediaType.APPLICATION_OCTET_STREAM) .contentLength(resource.contentLength()) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8) + "\"") .body(resource); }
- 第四步:如果排查下来是过滤器/拦截器篡改了响应头,可以在下载接口返回前手动设置需要的响应头,或者配置过滤器排除该接口的头处理逻辑。
内容的提问来源于stack exchange,提问作者Eatsam ul haq
相关产品推荐
相关产品推荐

