一、前言
在日常开发中,文件上传和下载是非常常见的功能场景,比如用户头像上传、文档下载、附件管理等。本文将基于 SpringBoot 框架,实现一套简洁、通用、可直接上线使用的文件上传与下载接口,包含空文件校验、目录自动创建、文件名防重复、文件不存在处理等核心逻辑。
二、环境准备
SpringBoot 版本:2.x/3.x 通用(本文使用 3.x,jakarta 包)
核心依赖:spring-web(Web 开发必备)
配置文件:application.yml/application.properties
三、核心代码实现
- pom.xml 依赖(无需额外依赖,基础 Web 依赖即可)
xml
bash
<dependencies>
<!-- SpringBoot Web 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 工具类(可选,简化开发) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- 配置文件(application.yml)
配置文件上传的存储目录,灵活可配置,无需硬编码:
yaml
bash
server:
port: 8080
#文件上传配置
file:
上传文件存储路径(Windows:D:/upload Linux:/home/upload)
upload-dir: D:/springboot-file-upload
- 文件上传下载控制器(FileController)
完整整合版代码,包含上传 + 下载接口,直接复制使用:
java
运行
bash
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.UUID;
/**
* 文件上传下载控制器
* @author 你的昵称
*/
@RestController
@RequestMapping("/file")
public class FileController {
// 从配置文件读取上传目录
@Value("${file.upload-dir}")
private String uploadDir;
/**
* 文件上传接口
* @param file 前端传递的文件(form-data 格式)
* @return 上传结果+唯一文件名
* @throws IOException IO异常
*/
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
// 1. 空文件校验
if (file.isEmpty()) {
return "上传失败:文件不能为空";
}
// 2. 自动创建上传目录(不存在则创建)
File directory = new File(uploadDir);
if (!directory.exists()) {
directory.mkdirs();
}
// 3. 生成唯一文件名(防止文件名重复覆盖)
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID() + suffix;
// 4. 构建文件最终存储路径
File destFile = new File(uploadDir + File.separator + fileName);
// 5. 写入文件到本地
file.transferTo(destFile);
// 返回唯一文件名(前端下载时需要传递此文件名)
return "上传成功!唯一文件名:" + fileName;
}
/**
* 文件下载接口
* @param fileName 上传时返回的唯一文件名
* @param response 响应对象
* @throws IOException IO异常
*/
@GetMapping("/download")
public void download(@RequestParam("fileName") String fileName,
HttpServletResponse response) throws IOException {
// 1. 构建文件完整路径
String filePath = uploadDir + File.separator + fileName;
File file = new File(filePath);
// 2. 文件不存在校验
if (!file.exists()) {
response.getWriter().write("下载失败:文件不存在");
return;
}
// 3. 设置下载响应头(告诉浏览器这是下载文件)
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(fileName, "UTF-8"));
// 4. 读取文件流,输出到前端
try (FileInputStream fis = new FileInputStream(file);
OutputStream os = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int len;
// 循环读取文件,写入响应流
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
}
}
}
四、接口说明
- 文件上传接口
请求地址:http://localhost:8080/file/upload
请求方式:POST
请求参数:file(文件流,前端使用 form-data 格式传递)
返回结果:上传成功 / 失败提示 + 唯一文件名
核心特性:
自动校验空文件,避免无效上传
自动创建存储目录,无需手动新建文件夹
UUID 生成唯一文件名,解决同名文件覆盖问题 - 文件下载接口
请求地址:http://localhost:8080/file/download
请求方式:GET
请求参数:fileName(上传接口返回的唯一文件名)
返回结果:浏览器自动下载文件
核心特性:
校验文件是否存在,友好提示
解决中文文件名乱码问题
流式输出,支持大文件下载
五、测试接口 - 上传测试
使用 Postman/Apicap 工具:
请求方式选 POST,地址填 /file/upload
Body 选择 form-data,key 填 file,类型选择 File
选择本地文件,点击发送,返回成功提示 + 唯一文件名 - 下载测试
浏览器 / 接口工具直接请求:http://localhost:8080/file/download?fileName=上传返回的唯一文件名
浏览器会自动触发文件下载
六、注意事项
路径适配:Windows 系统路径用 D:/upload,Linux 系统用 /home/upload
文件大小限制:SpringBoot 默认文件上传大小有限制,可在配置文件添加:
yaml
bash
spring:
servlet:
multipart:
max-file-size: 10MB # 单个文件最大大小
max-request-size: 100MB # 单次请求最大大小
权限问题:Linux 服务器需确保应用对上传目录有读写权限
生产环境:建议搭配 Nginx 做文件访问代理,或使用云存储(OSS/COS)
七、总结
本文实现的 SpringBoot 文件上传下载功能,代码简洁、逻辑完整、无第三方依赖,非常适合新手学习和中小型项目直接使用。核心知识点:
MultipartFile 处理文件上传
UUID 防止文件名重复
响应流实现文件下载
基础校验提升接口健壮性
需要源码的小伙伴可以直接复制本文代码,开箱即用!有问题欢迎评论区交流~