spring mvc 文件上传下载需正确配置multipart、安全使用multipartfile及响应流:上传时校验空文件、用transferto保存、流处理用try-with-resources;下载时设响应头、用files.copy写入、不close响应流;注意容器级限制与io陷阱。

Spring MVC 提供了对文件上传和下载的完整支持,核心在于正确配置、使用标准 Servlet API 封装的抽象类(如 MultipartFile),并合理管理 IO 流——避免内存溢出、确保流及时关闭、防止资源泄漏。
文件上传:接收并安全保存 MultipartFile
Spring 会自动将 multipart 请求解析为 MultipartFile 对象。关键不是“怎么读流”,而是“怎么用好它已封装的 API”,避免手动调用 getInputStream() 带来风险。
- 控制器方法直接接收
@RequestParam("file") MultipartFile file,无需自己解析原始流 - 务必先检查
file.isEmpty(),防止空文件导致后续 NPE 或异常写入 - 优先使用
file.transferTo(File dest)保存文件——它内部已做流复制与关闭,比手动copy(InputStream, OutputStream)更安全 - 若需流式处理(如校验内容、分块读取),用 try-with-resources 包裹
file.getInputStream(),例如:try (InputStream is = file.getInputStream()) { /* 处理逻辑 */ }
文件下载:设置响应头 + 正确写出字节流
下载本质是把文件内容写入 HttpServletResponse.getOutputStream(),重点是响应头设置和流控制。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 必须设置
Content-Type(如response.setContentType("application/octet-stream"))和Content-Disposition(含 filename,注意中文需URLEncoder.encode) - 推荐使用
Files.copy(Path source, OutputStream out)或FileCopyUtils.copy(File, OutputStream),它们自动处理缓冲与关闭 - 若手动操作流,务必用 try-with-resources 获取
response.getOutputStream(),但注意:Servlet 容器管理该流,**不应主动 close()**,只需 flush 即可 - 大文件下载建议设置
response.setContentLengthLong(file.length()),帮助浏览器预估进度
配置要点:启用 multipart 并调优参数
没有正确配置,上传请求根本到不了 Controller。
- Spring Boot 2.0+ 默认启用 multipart,可通过
spring.servlet.multipart.*配置项调整(如max-file-size=10MB) - 传统 XML 或 Java Config 方式需注册
CommonsMultipartResolver或StandardServletMultipartResolver(后者为推荐,基于 Servlet 3.0+ 原生支持) - 注意容器级限制:Tomcat 的
maxSwallowSize、Jetty 的maxFormSize也需同步调整,否则上传超限会直接 400 错误
IO 流常见陷阱与规避方式
很多问题源于对流生命周期理解偏差。
-
不要重复调用
getInputStream():MultipartFile 的流只能读一次,二次调用抛IllegalStateException - 不要在 Controller 层长期持有 InputStream/OutputStream:应尽快完成读写,避免阻塞线程或连接超时
-
临时文件清理:
MultipartFile在请求结束时由 Spring 自动清理,但若调用file.transferTo()成功,原始临时文件即被移走,无需额外处理 -
异步场景慎用流:若需异步处理上传文件,必须先将内容复制到新位置(如
transferTo()或Files.write()),再交由异步任务,不可传递原始MultipartFile或其流
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










