目录

在SpringBoot中,使用MultipartFile上传文件

在SpringBoot中,使用MultipartFile上传文件

在Spring Boot中, MultipartFile 是处理文件上传的核心类,通常用于接收客户端上传的文件数据。以下是详细的使用说明:


1. 基本概念

  • MultipartFile 是Spring框架提供的一个接口,封装了上传文件的所有信息(如文件内容、文件名、类型等)
  • 通常与 @RequestParam@ModelAttribute 结合使用,在Controller中接收文件

2. 前置配置

application.properties 中配置文件上传参数:

# 单个文件最大大小(默认1MB)
spring.servlet.multipart.max-file-size=10MB
# 单次请求总文件最大大小(默认10MB)
spring.servlet.multipart.max-request-size=50MB
# 文件存储临时目录(可选)
spring.servlet.multipart.location=/tmp

3. 基础使用示例

3.1 单个文件上传
@PostMapping("/upload")
public String uploadFile(
    @RequestParam("file") MultipartFile file,
    Model model) {

    if (file.isEmpty()) {
        model.addAttribute("message", "请选择要上传的文件");
        return "uploadStatus";
    }

    try {
        // 获取文件信息
        String fileName = file.getOriginalFilename();
        String contentType = file.getContentType();
        long size = file.getSize();

        // 保存文件到本地
        byte[] bytes = file.getBytes();
        Path path = Paths.get("uploads/" + fileName);
        Files.write(path, bytes);

        model.addAttribute("message", "文件上传成功: " + fileName);
    } catch (IOException e) {
        model.addAttribute("message", "文件上传失败: " + e.getMessage());
    }
    return "uploadStatus";
}
3.2 多个文件上传
@PostMapping("/multiUpload")
public String multiUpload(
    @RequestParam("files") MultipartFile[] files,
    Model model) {

    List<String> messages = new ArrayList<>();
    for (MultipartFile file : files) {
        if (file.isEmpty()) continue;
        try {
            String fileName = file.getOriginalFilename();
            file.transferTo(new File("uploads/" + fileName));
            messages.add("成功上传: " + fileName);
        } catch (IOException e) {
            messages.add("上传失败: " + file.getOriginalFilename());
        }
    }
    model.addAttribute("messages", messages);
    return "uploadStatus";
}

4. MultipartFile 核心方法

方法说明
String getOriginalFilename()获取原始文件名(含扩展名)
String getName()获取表单中的参数名(即@RequestParam中的name值)
String getContentType()获取文件MIME类型(如 image/png)
boolean isEmpty()判断文件是否为空
long getSize()获取文件大小(字节数)
byte[] getBytes()获取文件字节数组
InputStream getInputStream()获取文件输入流
void transferTo(File dest)将文件保存到指定路径

5. 最佳实践

5.1 文件存储路径处理
// 创建存储目录(如果不存在)
File uploadDir = new File("uploads");
if (!uploadDir.exists()) {
    uploadDir.mkdirs();
}

// 生成唯一文件名(避免覆盖)
String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
5.2 使用transferTo()方法

更高效的保存方式:

File dest = new File("uploads/" + fileName);
file.transferTo(dest); // 直接传输文件无需手动处理流

6. 异常处理

处理文件大小超出限制异常:

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<String> handleMaxSizeException() {
        return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE)
               .body("文件大小超过限制");
    }
}

7. 前端表单示例

HTML表单需要设置 enctype="multipart/form-data"

<form method="POST" action="/upload" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">上传</button>
</form>

8. 测试工具

  • Postman :选择 Body -> form-data ,类型选 File
  • Curl命令
curl -F "file=@/path/to/local/file.jpg" http://localhost:8080/upload

9. 常见问题解决

  1. 文件上传后大小为0

    • 检查表单是否设置 enctype="multipart/form-data"
    • 检查是否使用了正确的 @RequestParam 名称
  2. 中文文件名乱码

    application.properties 添加:

    spring.servlet.multipart.resolve-lazily=true
    spring.http.encoding.charset=UTF-8
    spring.http.encoding.enabled=true

通过以上步骤,你可以完整掌握Spring Boot中 MultipartFile 的使用方法。实际开发中建议结合云存储(OSS)或文件服务器处理大文件存储。