Spring Boot报错:无ByteArrayOutputStream转换器,求解决方案
问题分析与解决方案
问题本质
Spring MVC默认没有针对ByteArrayOutputStream的消息转换器,即便你在@RequestMapping中指定了produces = MediaType.APPLICATION_PDF_VALUE,框架也无法识别该返回类型并完成响应体的序列化,最终触发HttpMessageNotWritableException。
修正方案
你不需要直接操作HttpServletResponse,只需要将返回类型改为Spring原生支持的byte[]或ResponseEntity<byte[]>即可,以下是两种实现方式:
方式1:返回byte[](简洁版)
利用@RequestMapping的produces属性自动设置Content-Type:
@RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.APPLICATION_PDF_VALUE) public byte[] downloadSlidesAsPdf(@RequestParam String fileId) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); driveService.files().export(fileId, "application/pdf").executeMediaAndDownloadTo(outputStream); return outputStream.toByteArray(); }
方式2:返回ResponseEntity<byte[]>(支持自定义响应头)
可以直接配置文件名,解决下载文件无扩展名的问题,同时完全符合Spring MVC的设计规范:
@RequestMapping(value = "/test", method = RequestMethod.GET) public ResponseEntity<byte[]> downloadSlidesAsPdf(@RequestParam String fileId) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); driveService.files().export(fileId, "application/pdf").executeMediaAndDownloadTo(outputStream); byte[] pdfBytes = outputStream.toByteArray(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); // 自定义下载文件名,自动带上.pdf扩展名 headers.setContentDispositionFormData("attachment", "exported-document.pdf"); return new ResponseEntity<>(pdfBytes, headers, HttpStatus.OK); }
补充说明
- 返回
byte[]时,Spring的ByteArrayHttpMessageConverter会自动处理响应序列化,并应用@RequestMapping中指定的Content-Type。 - 使用
ResponseEntity不仅能解决扩展名问题,还能灵活控制响应状态码、额外响应头,比直接操作HttpServletResponse更符合Spring的设计理念,不属于workaround。
内容的提问来源于stack exchange,提问作者Matej Martincevic
相关产品推荐
相关产品推荐

