spring mvc 文件下载核心是设置 content-disposition 和 content-type 响应头,推荐用 responseentity 封装字节数组、响应头与状态码;中文文件名需兼容处理,避免手动操作 outputstream。

Spring MVC 处理文件下载的核心是控制 HTTP 响应头,让浏览器明确“这不是要展示的页面,而是需要保存的文件”。关键不在于返回什么类型的数据,而在于告诉浏览器怎么对待它。
必须设置的两个响应头
浏览器是否弹出下载对话框,主要取决于以下两个响应头:
-
Content-Disposition:值设为
attachment; filename="xxx",其中attachment表示强制下载;filename后跟用户看到的默认文件名(注意编码问题) -
Content-Type:推荐统一设为
application/octet-stream,表示通用二进制流。若已知具体类型(如 PDF、图片),也可用application/pdf或image/png,但非必需
推荐用 ResponseEntity 实现
这是最简洁、可控的方式,把文件内容、响应头、状态码一次封装返回:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 读取文件为字节数组(可用
FileUtils.readFileToByteArray()或StreamUtils.copyToByteArray()) - 构造
HttpHeaders,调用setContentDispositionFormData("attachment", fileName)(Spring 5.1+ 推荐) - 设置
contentType为MediaType.APPLICATION_OCTET_STREAM - 返回
new ResponseEntity<byte>(bytes, headers, HttpStatus.OK)</byte>
中文文件名兼容处理
不同浏览器对 UTF-8 文件名支持不一,尤其 IE/Edge 需转 ISO-8859-1 编码:
- 先将原始文件名按 UTF-8 编码成字节,再用 ISO-8859-1 解码成字符串(即
new String(fileName.getBytes("UTF-8"), "ISO-8859-1")) - 更现代的做法是使用
ContentDisposition.attachment().filename("中文名.pdf", StandardCharsets.UTF_8).build()(Spring 5.0+ 支持filename*标准) - 若需兼容老旧浏览器,可结合 User-Agent 判断后动态选择编码策略
避免用 void 方法 + OutputStream 的陷阱
虽然用 HttpServletResponse 手动写输出流也能实现,但容易出错:
- 忘记调用
flush()或close()导致文件不完整 - 未设置
Content-Length,部分客户端无法显示进度 - 异常时响应流可能已提交,导致错误页无法正常渲染
-
ResponseEntity自动处理这些细节,更安全、更符合 Spring 风格
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










