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 filename="name"这一段是普通字段,后端会映射为@RequestParam("name") String name
1. MultipartFile 从哪里来?(它对应请求里的哪一部分)
一次 multipart/form-data 请求一般包含两类 part:
- 普通字段 (文本字段):例如
name=xxx、type=pdf - 文件字段 (二进制/流):例如
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. 常见坑与安全建议
-
接口参数用错注解
- 上传文件用
@RequestParam MultipartFile file(或@RequestPart也常见) - 不要用
@RequestBody MultipartFile(通常不工作)
- 上传文件用
-
Content-Type 不对
- 必须是
multipart/form-data,否则MultipartFile可能接收不到。
- 必须是
-
文件名不可信(路径穿越)
getOriginalFilename()可能包含奇怪字符或路径(如../../a.txt)。- 建议:生成服务端文件名(UUID),并做后缀白名单校验。
-
大文件不要
getBytes()getBytes()会把文件一次性读入内存,可能 OOM。- 推荐
getInputStream()流式处理,或直接transferTo()。
-
校验文件类型不要只看 contentType
contentType可能被伪造。- 更稳妥做法:结合文件后缀白名单 + 魔数检测/解析库校验。
6. 一句话总结
MultipartFile表示一次multipart/form-data上传中的文件字段。- 常与
@RequestParam搭配:@RequestParam("file") MultipartFile file。 - 可通过
getOriginalFilename()/getSize()/getInputStream()/transferTo()获取信息与保存文件。