Spring MVC:MultipartFile 详解

Spring MVC MultipartFile 详解

适用范围:Spring MVC / Spring Boot 文件上传(multipart/form-data)

MultipartFile 是 Spring Web 提供的一个接口(org.springframework.web.multipart.MultipartFile),用于表示一次 HTTP multipart 上传请求中的单个文件字段。

简单理解:

  • 前端用 <input type="file"> 或表单上传文件时(示例见下)
  • 请求的 Content-Type 通常是:multipart/form-data
  • Spring 会把文件部分解析出来,并封装成 MultipartFile 交给你的 Controller

示例 1:HTML 表单上传(浏览器)

html 复制代码
<form action="/admin/knowledge/upload" method="post" enctype="multipart/form-data">
  <input type="text" name="name" placeholder="文档名称(可选)" />
  <input type="file" name="file" />
  <button type="submit">上传</button>
</form>

注意:enctype="multipart/form-data" 必须写,否则后端通常拿不到 MultipartFile。

示例 2:前端使用 JavaScript(fetch + FormData)

js 复制代码
const formData = new FormData();
formData.append('name', '我的文档');
formData.append('file', fileInput.files[0]);

fetch('/admin/knowledge/upload', {
  method: 'POST',
  body: formData,
});

示例 3:HTTP 请求格式示例(multipart/form-data 原始报文示意)

说明:实际请求里的 boundary 是由客户端自动生成的一段随机字符串。下面仅演示结构,方便理解 MultipartFile 对应的是哪一段。

http 复制代码
POST /admin/knowledge/upload HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"

我的文档
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="a.pdf"
Content-Type: application/pdf

%PDF-1.7
...(二进制内容省略)...
------WebKitFormBoundary7MA4YWxkTrZu0gW--

你可以对照看到:

  • name="file"; filename="a.pdf" 这一段就是文件 part,后端会映射为 @RequestParam("file") MultipartFile file
  • name="name" 这一段是普通字段,后端会映射为 @RequestParam("name") String name

1. MultipartFile 从哪里来?(它对应请求里的哪一部分)

一次 multipart/form-data 请求一般包含两类 part:

  1. 普通字段 (文本字段):例如 name=xxx、type=pdf
  2. 文件字段 (二进制/流):例如 file=<某个文件>

在 Controller 中:

  • 普通字段通常用 @RequestParam String name 接收
  • 文件字段用 @RequestParam MultipartFile file 接收

2. 实际例子

2.1 单文件上传

java 复制代码
@PostMapping("/upload")
public BaseResponse<KnowledgeDocument> uploadDocument(
        @RequestParam("file") MultipartFile file,
        @RequestParam(value = "name", required = false) String name) {
    // ...
}

含义:

  • 请求必须是 multipart/form-data
  • 表单里文件字段名必须叫 file
  • name 是可选的普通字段

2.2 多文件上传

java 复制代码
@PostMapping("/batch-upload")
public BaseResponse<BatchUploadResultVO> batchUploadDocuments(
        @RequestParam("files") MultipartFile[] files,
        @RequestParam(value = "names", required = false) List<String> names) {
    // ...
}

含义:

  • 文件字段名是 files
  • 上传多个文件时,后端可以用 MultipartFile[] 或 List<MultipartFile> 接收

3. 常用方法速查

MultipartFile 常用方法(非常实用):

  • String getName():表单字段名(如 file / files)
  • String getOriginalFilename():客户端原始文件名(如 xxx.pdf)
  • String getContentType():MIME 类型(如 application/pdf)
  • boolean isEmpty():是否为空文件/未选择文件
  • long getSize():文件大小(字节)
  • byte[] getBytes():一次性读入内存(小文件可用)
  • InputStream getInputStream():以流方式读取(推荐处理大文件)
  • void transferTo(File dest):保存到磁盘文件

示例:

java 复制代码
if (file.isEmpty()) {
    throw new IllegalArgumentException("文件为空");
}

String originalName = file.getOriginalFilename();
long size = file.getSize();
String contentType = file.getContentType();

// 保存到本地(示例)
File dest = new File("D:/upload/" + originalName);
file.transferTo(dest);

4. Spring Boot 上传配置要点(application.yml)

Spring Boot 默认已支持 multipart,但通常你会配置大小限制:

yaml 复制代码
spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 50MB
      max-request-size: 100MB
  • max-file-size:单个文件最大大小
  • max-request-size:整个请求最大大小(多文件时会更大)

5. 常见坑与安全建议

  1. 接口参数用错注解

    • 上传文件用 @RequestParam MultipartFile file(或 @RequestPart 也常见)
    • 不要用 @RequestBody MultipartFile(通常不工作)
  2. Content-Type 不对

    • 必须是 multipart/form-data,否则 MultipartFile 可能接收不到。
  3. 文件名不可信(路径穿越)

    • getOriginalFilename() 可能包含奇怪字符或路径(如 ../../a.txt)。
    • 建议:生成服务端文件名(UUID),并做后缀白名单校验。
  4. 大文件不要 getBytes()

    • getBytes() 会把文件一次性读入内存,可能 OOM。
    • 推荐 getInputStream() 流式处理,或直接 transferTo()。
  5. 校验文件类型不要只看 contentType

    • contentType 可能被伪造。
    • 更稳妥做法:结合文件后缀白名单 + 魔数检测/解析库校验。

6. 一句话总结

  • MultipartFile 表示一次 multipart/form-data 上传中的文件字段。
  • 常与 @RequestParam 搭配:@RequestParam("file") MultipartFile file。
  • 可通过 getOriginalFilename()/getSize()/getInputStream()/transferTo() 获取信息与保存文件。
相关推荐
倔强的石头10632 分钟前
【Linux指南】进程通信系列(二):匿名管道 —— pipe 的本质、fork 继承与四种读写规则
java·linux·运维
调试优选官37 分钟前
2026年IoT物联网开发赛道年度榜单深度解析:D-coding物联网系统定制与源码交付能力专项解读
java·物联网·struts·iot·开发经验
木井巳39 分钟前
【动态规划】三步问题
java·算法·leetcode·动态规划·推荐算法
小张成长计划..42 分钟前
【Linux】25:线程概念和控制
java·linux·jvm
蛋蛋的就会顺顺的10 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要82610 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡10 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
伯恩bourne12 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_13 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs13 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构