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=xxxtype=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() 获取信息与保存文件。
相关推荐
JavaLearnerZGQ1 小时前
Spring SseEmitter 全面解析与使用示例
java·后端·spring
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧1 小时前
Jsoup: 一款Java的HTML解析器
java·开发语言·前端·后端·缓存·html
Protein_zmm1 小时前
【算法基础】位运算、离散化、区间合并
java·算法·spring
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧1 小时前
JSP, MVC, El, JSTL, MAC
java·开发语言·mvc·mac·jsp
黎雁·泠崖2 小时前
Java 数据结构与算法:时间空间复杂度 从入门到实战全解
java·开发语言
Coder_Boy_2 小时前
技术交流总结:分布式、数据库、Spring及SpringBoot核心知识点梳理(实现参考)
数据库·spring boot·分布式·spring·架构
想不明白的过度思考者2 小时前
Spring Boot 实战:MyBatis 操作数据库(上)
java·数据库·spring boot·mysql·mybatis
wuqingshun3141592 小时前
简述双亲委派机制以及其优点
java·开发语言·jvm
七夜zippoe2 小时前
微服务链路追踪实战:SkyWalking vs Zipkin 架构深度解析与性能优化指南
java·开发语言·微服务·springcloud·sleuth·zipkin