Java中下载文件无法打开问题排查及代码修正请求
问题分析与解决方案
你的代码处理非文本类文件失败的核心原因是错误地对二进制数据进行了字符串转换:Base64解码后得到的是原始二进制字节数组,你将其转为String再转回byte[],这个过程会因为字符编码的问题破坏二进制数据(比如PDF、图片中的非可打印字符),导致文件损坏无法打开。
修正后的代码
Controller 无需修改
public class downloadController { @Autowired DownloadService downloadService; @GetMapping("/download") public ResponseEntity<Resource> download() { return downloadService.download(); } }
修改后的 DownloadService
public class DownloadService { @Autowired RestTemplate restTemplate; public ResponseEntity<Resource> download() { // 调整restTemplate.exchange的返回逻辑,直接获取Base64编码的字符串响应 String base64Response = restTemplate.exchange(......, String.class).getBody(); // 直接解码得到原始二进制字节数组,跳过String转换步骤 byte[] fileBytes = Base64.getDecoder().decode(base64Response); Resource resource = new ByteArrayResource(fileBytes); // 后续可替换为动态获取的文件名和MediaType String fileName = "report.pdf"; MediaType mediaType = MediaType.APPLICATION_PDF; return ResponseEntity.ok() .header(HttpHeader.CONTENT_DISPOSITION, "attachment;filename=\"" + fileName + "\"") .contentType(mediaType) .body(resource); } }
动态处理文件类型的建议
- 获取文件名与扩展名:可以从下游接口的响应头(比如
Content-Disposition)、请求参数或者业务逻辑中动态获取文件名,解析出扩展名。 - 映射对应的MediaType:
- 使用
MediaTypeFactory.getMediaType(fileName).orElse(MediaType.APPLICATION_OCTET_STREAM)自动根据文件名推断MediaType - 或者维护一个扩展名到MediaType的映射表,手动匹配
- 使用
内容的提问来源于stack exchange,提问作者Iswarya Elango
相关产品推荐
相关产品推荐

