一、前言

文件上传与下载是 Web 系统中最常见的应用功能,比如用户头像的上传、Excel 文件的导入和导出等。我们通过SpringBoot整合MultipartFile可以很方便的实现文件的上传和下载。

二、项目实践

1.引入相关依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

2.添加相关配置参数

#是否开启文件上传
spring.servlet.multipart.enabled=true
#表示上传的单个文件的最大大小,默认为 1MB
spring.servlet.multipart.max-file-size=10MB
# 表示多文件上传时文件的总大小,默认为 10MB
spring.servlet.multipart.max-request-size=10MB
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

3.单文件上传示例

在src/main/resources/templates目录下,创建一个简单的单文件上传页面upload.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单文件上传</title>
</head>
<body>
  <form method="post" enctype="multipart/form-data" action="/fileUpload">
    文件:<input type="file" name="file"/><br/>
    <input type="submit" value="提交"/>
  </form>
</body>
</html>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

对应的Controller类,示例如下:

package com.example.dataproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @author qx
 * @date 2024/8/21
 * @des
 */
@Controller
public class UploadController {

    @GetMapping("/toUpload")
    public String index() {
        return "upload";
    }

    @PostMapping("/fileUpload")
    @ResponseBody
    public String fileUpload(MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return "请上传文件";
        }
        String fileName = file.getOriginalFilename();
        //保存路径
        String absoultePath = "D:" + File.separator + "uploads" + File.separator + fileName;
        file.transferTo(new File(absoultePath));
        return "upload success";
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.

启动服务后,访问http://localhost:8080/toUpload,可以看到如下界面:

SpringBoot整合 MultipartFile实现文件上传与下载_单文件上传

我们选择文件并上传。

SpringBoot整合 MultipartFile实现文件上传与下载_单文件上传_02

点击提交上传文件。

SpringBoot整合 MultipartFile实现文件上传与下载_单文件上传_03

我们在保存的目录中查看保存了新的图片文件。

SpringBoot整合 MultipartFile实现文件上传与下载_多文件上传_04

4.多文件上传示例

将服务端的接受文件参数改成数组即可,相关示例如下!

与上面类似,创建一个多文件上传页面uploadMulti.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多文件上传</title>
</head>
<body>
<form method="post" action="/multiFileUpload" enctype="multipart/form-data">
    文件1:<input type="file" name="files"><br>
    文件2:<input type="file" name="files"><br>
    <hr>
    <input type="submit" value="提交">
</form>
</body>
</html>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

对应的Controller类,内容如下:

package com.example.dataproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @author qx
 * @date 2024/8/21
 * @des
 */
@Controller
public class UploadMultiController {

    @GetMapping("/toUploadMulti")
    public String index() {
        return "uploadMulti";
    }

    /**
     * 多文件上传
     *
     * @param files
     * @return
     * @throws IOException
     */
    @PostMapping("/multiFileUpload")
    @ResponseBody
    public String fileUpload(MultipartFile[] files) throws IOException {
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                return "请上传文件";
            }
            String fileName = file.getOriginalFilename();
            //保存路径
            String absoultePath = "D:" + File.separator + "uploads" + File.separator + fileName;
            file.transferTo(new File(absoultePath));
        }
        return "upload files success";
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

启动服务后,访问http://localhost:8080/toUploadMulti,可以看到如下界面:

SpringBoot整合 MultipartFile实现文件上传与下载_多文件上传_05

选择文件并提交

SpringBoot整合 MultipartFile实现文件上传与下载_SpringBoot_06

SpringBoot整合 MultipartFile实现文件上传与下载_多文件上传_07

最后我们在保存目录里面查看到新增的两个图片文件。

SpringBoot整合 MultipartFile实现文件上传与下载_多文件上传_08

5.文件下载示例

文件下载功能,应用场景也特别多,通常以 restful 方式访问服务端并获取资源,通用实现示例如下:

package com.example.dataproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author qx
 * @date 2024/8/21
 * @des 下载控制层
 */
@Controller
public class DownloadController {

    @GetMapping("/download/{filename}")
    public void download(@PathVariable String filename, HttpServletResponse response) throws Exception {
        File file = new File("D:" + File.separator + "uploads" + File.separator + filename);
        if (!file.exists()) {
            throw new RuntimeException("下载的文件不存在");
        }
        response.reset();
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        response.setContentLength((int) file.length());
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));

        // 使用缓存流,边读边写
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            OutputStream os = response.getOutputStream();
            byte[] buff = new byte[1024];
            int i;
            while ((i = bis.read(buff)) != -1) {
                os.write(buff, 0, i);
                os.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException("下载文件失败");
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

重新启动程序,并请求下载文件。

SpringBoot整合 MultipartFile实现文件上传与下载_MultipartFile_09

SpringBoot整合 MultipartFile实现文件上传与下载_多文件上传_10

三、小结

本文学习了使用SpringBoot结合MultipartFile实现单文件、多文件的上传和文件的下载。