SpringBoot 框架实现文件上传下载分享

发布于:2025-06-10 ⋅ 阅读:(42) ⋅ 点赞:(0)

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);
    }

到此,文件上传下载分享完成,后期会分享站点上传数据,敬请期待。


网站公告

今日签到

点亮在社区的每一天
去签到