Spring MVC(非SpringBoot)集成Springfox 2.9.2下载PDF损坏问题排查
问题分析与解决
你的代码逻辑本身没有错误,但Springfox 2.9.2在处理二进制响应时存在兼容性问题:它会默认将响应字节流当作UTF-8字符串解析后再转成字节,导致PDF文件的二进制数据被篡改,所以通过swagger-ui下载的文件损坏;直接访问URL时绕过了Swagger的拦截逻辑,因此能正常下载。
以下是具体的解决方案:
1. 修正响应的Content-Type
将MediaType.APPLICATION_OCTET_STREAM替换为MediaType.APPLICATION_PDF,让Swagger明确识别这是PDF类型的响应,避免误处理:
return ResponseEntity.ok() .contentType(MediaType.APPLICATION_PDF) .contentLength(resource.contentLength()) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"test.pdf\"") .body(resource);
2. 配置Springfox正确处理二进制响应
在你的Swagger配置类中,为Docket指定响应的媒体类型,并配置消息转换器,确保二进制数据不被篡改:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("你的控制器包路径")) .paths(PathSelectors.any()) .build() .produces(Collections.singleton(MediaType.APPLICATION_PDF_VALUE)) .directModelSubstitute(Resource.class, byte[].class); } // 配置消息转换器,避免Swagger将二进制转成字符串 @Bean public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList( MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_PDF )); return converter; } }
3. 为接口添加Swagger注解明确响应类型
在接口方法上添加注解,指定响应的媒体类型和返回类型,帮助Swagger正确识别:
@RequestMapping(value = "/v1/generatePdfSync", method = RequestMethod.GET) @ApiOperation(value = "生成PDF文件", produces = MediaType.APPLICATION_PDF_VALUE) @ApiResponse(code = 200, message = "PDF文件", response = byte[].class) public ResponseEntity<Resource> generatePdfSync(@RequestParam String templateName) { // 原有代码不变 }
完成以上配置后,swagger-ui的「Download file」按钮就能正确下载未损坏的PDF文件了。
内容的提问来源于stack exchange,提问作者budikpet
相关产品推荐
相关产品推荐

