相关推荐recommended
Spring Boot 中实现文件上传、下载、删除功能
作者:mmseoamin日期:2024-01-30

Spring Boot 中实现文件上传、下载、删除功能,在这里插入图片描述,第1张

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。

🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。

🎉欢迎 👍点赞✍评论⭐收藏

🔎 SpringBoot 领域知识 🔎

链接专栏
SpringBoot 专业知识学习一SpringBoot专栏
SpringBoot 专业知识学习二SpringBoot专栏
SpringBoot 专业知识学习三SpringBoot专栏
SpringBoot 专业知识学习四SpringBoot专栏
SpringBoot 专业知识学习五SpringBoot专栏
SpringBoot 专业知识学习六SpringBoot专栏
SpringBoot 专业知识学习七SpringBoot专栏
SpringBoot 专业知识学习八SpringBoot专栏
SpringBoot 专业知识学习九SpringBoot专栏

Spring Boot 中实现文件上传、下载、删除功能,在这里插入图片描述,第2张

本文将详细介绍如何在 Spring Boot 中实现文件上传、下载、删除功能,采用的技术框架包括:Spring Boot 2.4.2、Spring MVC、MyBatis 3.5.6、Druid 数据源、JUnit 5 等。本文将按照以下步骤一步步实现,其中包括:

1. 创建数据库表

2. 配置文件的设置

3. 实体的创建

4. Mapper 和 DAO 的编写

5. Service 层的编写

6. Controller 层的编写

7. 其他注意事项

8. 实现总结

Spring Boot 中实现文件上传、下载、删除功能,在这里插入图片描述,第3张

在 Spring Boot 中实现文件上传、下载和删除功能


1. 创建数据库表

首先,我们需要创建一个用于存储文件信息的数据库表。在本例中,我们将使用 MySQL 数据库,并创建一个名为 files 的表,包含以下字段:

  • id:文件的唯一标识符,使用自增长主键
  • file_name:文件的名称
  • file_path:文件类型
  • file_size:文件大小
  • path:存储文件的文件保存路径
  • create_time:文件创建时间

    可以使用以下 SQL 语句创建这个表:

    CREATE TABLE `file` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '文件ID',
      `file_name` varchar(255) NOT NULL COMMENT '文件名',
      `file_type` varchar(100) NOT NULL COMMENT '文件类型',
      `file_size` varchar(255) NOT NULL COMMENT '文件大小',
      `file_path` varchar(255) NOT NULL COMMENT '文件保存路径',
      `create_time` datetime NOT NULL COMMENT '文件创建时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件存储表';
    

    2. 配置文件的设置

    在本文中,我们将使用 yml 文件进行配置。首先,我们需要配置数据库的连接信息和 MyBatis 的配置。我们还需要配置上传文件的路径和允许上传的文件大小。以下是在 Spring Boot 应用程序中添加配置的示例:

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        initialSize: 5
        maxActive: 20
        minIdle: 5
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        validationQuery: select 1 from dual
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20
        filters: stat,wall,log4j,config
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # Mybatis 配置
      mybatis:
        mapper-locations: classpath:mapper/*.xml
        type-aliases-package: com.example.demo.domain
      # 文件上传配置
      servlet:
        multipart:
          enabled: true
          max-file-size: 10MB
          max-request-size: 100MB
          location: /data/file-server/
    

    其中,datasource 部分是数据库连接信息的配置。Mybatis 部分配置了 Mybatis 的映射文件和实体类的位置。servlet 部分用于配置上传文件的大小和位置。


    3. 实体的创建

    在本文中,我们将创建 FileEntity 实体类,作为对文件信息的模型。以下是 FileEntity 类的示例:

    @Data
    public class FileEntity {
        private Integer id;
        private String name;
        private Long size;
        private String type;
        private String path;
        // 下面为 getter 和 setter 方法
    }
    

    注意,我们为每个字段添加了 getter 和 setter 方法,以便可以从数据库中读取和写入文件信息。


    4. Mapper 和 DAO 的编写

    在编写 Mapper 和 DAO 之前,我们需要在 pom.xml 文件中引入 Mybatis 和 Druid。

    
      org.mybatis.spring.boot
      mybatis-spring-boot-starter
      2.1.3
    
    
      com.alibaba
      druid
      1.2.4
    
    
        org.springframework.boot
        spring-boot-starter-web
    
    
        commons-fileupload
        commons-fileupload
        1.4
    
    

    创建 Mapper 接口和 XML 文件,使用 Mybatis 注解或 SQL 语句与数据库进行交互。

    为了实现上传、下载、删除功能,我们可能需要使用一些第三方包或工具类。以下是一个简单的基于Spring Boot的mapper示例,演示了如何使用七牛云存储实现上传、下载、删除文件:

    import java.io.File;
    import java.io.IOException;
    import com.qiniu.util.Auth;
    import com.qiniu.util.StringMap;
    import com.qiniu.http.Response;
    import com.qiniu.storage.Configuration;
    import com.qiniu.storage.Region;
    import com.qiniu.storage.UploadManager;
    import com.qiniu.storage.model.DefaultPutRet;
    import com.qiniu.storage.model.FileInfo;
    import com.qiniu.storage.BucketManager;
    import com.qiniu.common.QiniuException;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    @Component
    public class FileManager {
        @Value("${qiniu.accessKey}")
        private String accessKey;
        @Value("${qiniu.secretKey}")
        private String secretKey;
        @Value("${qiniu.bucket}")
        private String bucket;
        @Value("${qiniu.basePath}")
        private String basePath;
        private Auth auth;
        private Configuration cfg;
        private UploadManager uploadManager;
        private BucketManager bucketManager;
        public FileManager() {
            auth = Auth.create(accessKey, secretKey);
            cfg = new Configuration(Region.autoRegion());
            uploadManager = new UploadManager(cfg);
            bucketManager = new BucketManager(auth, cfg);
        }
        /**
         * 上传本地文件到七牛云
         */
        public String uploadFile(String filePath, String fileName) {
            String key = basePath + fileName;
            try {
                Response res = uploadManager.put(filePath, key, auth.uploadToken(bucket), null, null);
                DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
                return putRet.hash;
            } catch (QiniuException e) {
                return null;
            }
        }
        /**
         * 根据文件名从七牛云删除文件
         */
        public boolean deleteFile(String fileName) {
            try {
                bucketManager.delete(bucket, basePath + fileName);
                return true;
            } catch (QiniuException ex) {
                return false;
            }
        }
        /**
         * 根据文件名从七牛云获取文件信息
         */
        public FileInfo getFileInfo(String fileName) {
            try {
                return bucketManager.stat(bucket, basePath + fileName);
            } catch (QiniuException ex) {
                return null;
            }
        }
        /**
         * 根据文件名从七牛云下载文件到本地
         */
        public boolean downloadFile(String fileName, String localFilePath) {
            try {
                bucketManager.download(bucket, basePath + fileName, new File(localFilePath));
                return true;
            } catch (QiniuException ex) {
                return false;
            }
        }
    }
    

    这个示例利用了七牛云存储服务完成文件的上传、下载和删除操作。关键在于使用了七牛云存储提供的Java SDK,在代码中我们通过使用该SDK的函数实现对云上文件的操作。同时,我们需要在我们的Spring Boot项目中配置七牛云存储服务的 accessKey、secretKey 和 bucket 等参数。具体使用方法可以参照七牛云存储官方文档进行配置和使用。


    5. Service 层的编写

    5.1 接口层代码实现逻辑
    public interface StorageService {
        String save(MultipartFile file);
        Resource load(String filename);
        void delete(String filename);
    }
    
    5.2 接口实现层代码实现逻辑
    @Service
    public class LocalStorageService implements StorageService {
        private final Path storageLocation;
        @Autowired
        public LocalStorageService(@Value("${spring.servlet.multipart.location}") String storageLocation) {
            this.storageLocation = Paths.get(storageLocation);
        }
        @Override
        public String save(MultipartFile file) {
            // 实现文件保存的业务逻辑,如将文件保存到本地文件系统
            // 返回文件保存后的路径或 URL
            String filename = file.getOriginalFilename();
            Path targetLocation = this.storageLocation.resolve(filename);
            try {
                file.transferTo(targetLocation);
                return targetLocation.toString();
            } catch (IOException e) {
                throw new RuntimeException("Failed to save file: " + filename, e);
            }
        }
        @Override
        public Resource load(String filename) {
            // 实现文件加载的业务逻辑,如从本地文件系统读取文件并返回
            Path file = this.storageLocation.resolve(filename);
            Resource resource;
            try {
                resource = new UrlResource(file.toUri());
            } catch (MalformedURLException e) {
                throw new RuntimeException("Failed to load file: " + filename, e);
            }
            if (resource.exists() && resource.isReadable()) {
                return resource;
            } else {
                throw new RuntimeException("File not found: " + filename);
            }
        }
        @Override
        public void delete(String filename) {
            // 实现文件删除的业务逻辑,如从本地文件系统删除文件
            Path file = this.storageLocation.resolve(filename);
            try {
                Files.delete(file);
            } catch (IOException e) {
                throw new RuntimeException("Failed to delete file: " + filename, e);
            }
        }
    }
    

    6. Controller 层的编写

    创建文件上传控制器类,用于处理文件上传、下载和删除请求:

    @RestController
    public class FileController {
        @Autowired
        private StorageService storageService;
        @PostMapping("/upload")
        public String uploadFile(@RequestParam("file") MultipartFile file) {
            // 调用 storageService.save(file) 进行文件保存的业务逻辑
            // 返回处理结果,如文件的 URL 或保存路径等
            String filePath = storageService.save(file);
            return "File uploaded successfully!";
        }
        @GetMapping("/download/{filename}")
        public ResponseEntity downloadFile(@PathVariable String filename) {
            // 调用 storageService.load(filename) 进行文件下载的业务逻辑
            // 创建 Resource 对象,将文件流作为响应体返回
            Resource fileResource = storageService.load(filename);
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .body(fileResource);
        }
        @DeleteMapping("/delete/{filename}")
        public String deleteFile(@PathVariable String filename) {
            // 调用 storageService.delete(filename) 进行文件删除的业务逻辑
            storageService.delete(filename);
            return "File deleted successfully!";
        }
    }
    

    7. 其他注意事项

    除了上述提到的注意事项之外,实现文件上传、下载和删除功能时还应注意以下几点:

    7.1 文件大小限制: 为了避免恶意用户上传过大的文件导致服务器资源耗尽,应该 对上传文件的大小进行限制 。你可以在application.yml中使用以下配置设置上传文件的最大大小(单位为字节):

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        initialSize: 5
        maxActive: 20
        minIdle: 5
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        validationQuery: select 1 from dual
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20
        filters: stat,wall,log4j,config
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # Mybatis 配置
      mybatis:
        mapper-locations: classpath:mapper/*.xml
        type-aliases-package: com.example.demo.domain
      # 文件上传配置
      servlet:
        multipart:
          enabled: true
          max-file-size: 10MB
          max-request-size: 100MB
          location: /data/file-server/
    

    在上述示例中,文件最大大小被限制为10MB。你可以根据需要进行调整。

    7.2 文件类型限制: 在文件上传时,你可以通过文件的扩展名或MIME类型进行检查,以确保只接受指定类型的文件。例如,你可以使用Java的正则表达式或Apache Tika等库来验证文件的扩展名或MIME类型。

    7.3 安全性考虑: 文件上传功能可能会面临一些安全威胁,如 文件包含漏洞(如路径遍历攻击)、恶意文件上传或执行 ,你应该采取相应的安全措施来防止这些威胁。例如,可以对文件名进行过滤,禁止某些关键词,或者对上传的文件进行杀毒扫描。

    7.4 跨域请求问题: 当实现文件上传、下载和删除功能时,你可能会遇到 跨域请求 问题。如果你的前端应用与后端应用分别部署在不同的域中,你需要在后端应用中进行跨域配置,以允许来自其他域的请求。

    7.5 文件存储策略: 对于大规模的文件上传和下载应用,仅仅保存文件到本地可能不够有效或可扩展。你可以考虑使用云存储服务(如Amazon S3、阿里云OSS)或分布式文件系统(如GlusterFS、Ceph等)来存储和管理上传的文件。

    7.6 异步处理: 对于大文件上传或下载的情况,可以考虑使用异步处理来提高性能和用户体验。你可以利用Spring Boot的异步特性(如@Async注解和DeferredResult对象)来实现异步处理。

    在实现文件上传、下载和删除功能时,以上是一些常见的注意事项。根据你的具体需求和应用背景,可能还有其他的注意事项需要注意。希望这些信息能对你有所帮助。如果有更多问题,请随时提问。


    8. 实现总结

    通过完成上述步骤,我们成功实现了在 Spring Boot 中的文件上传、下载和删除功能,包括创建数据库表、文件上传功能、文件下载功能和文件删除功能。

    在实现这些功能时,我们还学习了一些重要的注意事项。例如,在文件上传时,需要确保保存文件的目录存在;在文件下载和删除时,需要确保文件存在。

    综上所述,Spring Boot 提供了强大的工具和简化的方式来实现文件上传、下载和删除功能,使我们能够轻松地构建功能完善的 Web 应用程序。这些功能可以满足实际项目中的需求,为用户提供便捷的文件操作体验。

    Spring Boot 中实现文件上传、下载、删除功能,在这里插入图片描述,第4张