SpringBoot 框架实现文件上传下载分享
SpringBoot 文件上传下载是我们常用的功能,比如图片、视频上传、下载和更新等功能的实现。下面我们详细分析一下:
1、pom.xml包引入
<!-- 基础 web 依赖(包含文件上传支持) -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- 文件操作工具类 -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>
2、存储目录设计
/data/project_files/
├── images/
│ ├── 202405/
│ └── 202406/
└── videos/
├── 202405/
└── 202406/
- 使用
UUID
生成唯一文件名(保留原始扩展名) - 按年月生成子目录(防止单目录文件过多)
- 推荐存储绝对路径到数据库(如:
/images/202405/uuid123.jpg
)
3、配置文件信息
# win环境文件存储根目录
file.upload-dir=D:/data/project_files/#linux环境
file.upload-dir=/data/project_files/# 上传大小限制(默认1MB,按需调整)
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
4、上传接口
@PostMapping("/upload")
public ApiResult uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String fileType) throws IOException {// 验证文件类型if (!Arrays.asList("image", "video").contains(fileType)) {return ApiResult.error("Invalid file type");}// 生成存储路径String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));String fileExt = FilenameUtils.getExtension(file.getOriginalFilename());String uuid = UUID.randomUUID().toString();String relativePath = String.format("/%s/%s/%s.%s", fileType + "s", datePath, uuid, fileExt);// 保存文件File dest = new File(uploadDir + relativePath);FileUtils.forceMkdirParent(dest);file.transferTo(dest);return ApiResult.ok(relativePath);}
直接获取下载地址上传方式
@PostMapping("/uploadFile")@ApiOperation(value="文件上传",notes = "文件上传-√")public String uploadFile(@RequestParam("file")MultipartFile file, @RequestParam String fileType) throws IOException {// 验证文件类型if (!Arrays.asList("image", "video").contains(fileType)) {return CommonResponse.buildErrorResponse("Error file type");}// 生成存储路径String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));String fileExt = FilenameUtils.getExtension(file.getOriginalFilename());String uuid = UUID.randomUUID().toString();String relativePath = String.format("/%s/%s/%s.%s",fileType + "s", datePath, uuid, fileExt);// 保存文件File dest = new File(uploadDir + relativePath);FileUtils.forceMkdirParent(dest);file.transferTo(dest);log.info("filePath:{}",fileIpPortUrl+relativePath);return (fileIpPortUrl+relativePath);}
5、下载接口
1)接口下载
@GetMapping("/download")public ResponseEntity<Resource> downloadFile(@RequestParam String filePath) throws IOException {Path path = Paths.get(uploadDir + filePath);Resource resource = new UrlResource(path.toUri());return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"").body(resource);}
2)原路径获取下载
@GetMapping("/download/**")@ApiOperation(value="文件下载接口",notes = "文件下载接口-√")public ResponseEntity<Resource> downloadFile(HttpServletRequest request) throws IOException {// 获取完整文件路径(需截掉前缀路径)String filePath = request.getServletPath().replaceFirst("/file/******/", "");log.info("filePath:{}",filePath);// 路径安全校验if (filePath.contains("..")) {return ResponseEntity.badRequest().build();}Path path = Paths.get(uploadDir + File.separator + filePath);log.info("path:{}",path);Resource resource = new UrlResource(path.toUri());log.info("toUri:{}",path.toUri());if (!resource.exists()) {return ResponseEntity.notFound().build();}return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=\"" + resource.getFilename() + "\"").body(resource);}
6、修改文件
@PostMapping("/update")public ApiResult updateFile(@RequestParam("file") MultipartFile file,@RequestParam String oldFilePath) throws IOException {// 删除旧文件File oldFile = new File(uploadDir + oldFilePath);if (oldFile.exists()) {FileUtils.forceDelete(oldFile);}// 上传新文件(复用上传逻辑)return uploadFile(file, parseFileType(oldFilePath));}
或者
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.UUID;@PostMapping("/update")public String updateFile(@RequestParam("file") MultipartFile file,@RequestParam String oldFilePath, @RequestParam String fileType) throws IOException {// 删除旧文件File oldFile = new File(uploadDir + oldFilePath);if (oldFile.exists()) {FileUtils.forceDelete(oldFile);}// 上传新文件(复用上传逻辑)return uploadFile(file, fileType);}
到此,文件上传下载分享完成,后期会分享站点上传数据,敬请期待。