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

在这里插入图片描述

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
🎉欢迎 👍点赞✍评论⭐收藏

🔎 SpringBoot 领域知识 🔎

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

在这里插入图片描述

本文将详细介绍如何在 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 中实现文件上传、下载和删除功能


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。

<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>2.1.3</version>
</dependency>

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.4</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

创建 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项目中配置七牛云存储服务的 accessKeysecretKeybucket 等参数。具体使用方法可以参照七牛云存储官方文档进行配置和使用。


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<Resource> 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 应用程序。这些功能可以满足实际项目中的需求,为用户提供便捷的文件操作体验。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/321790.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【RPC】序列化:对象怎么在网络中传输?

今天来聊下RPC框架中的序列化。在不同的场景下合理地选择序列化方式&#xff0c;对提升RPC框架整体的稳定性和性能是至关重要的。 一、为什么需要序列化&#xff1f; 首先&#xff0c;我们得知道什么是序列化与反序列化。 网络传输的数据必须是二进制数据&#xff0c;但调用…

Jenkins-Maven Git

整合Maven 安装GIT #更新yum sudo yum update #安装git yum install git 安装Maven插件,在插件管理中心&#xff1a; 配置仓库 配置密码认证 我们可以在这个目录下看到Jenkins 帮我们拉取了代码 /env/liyong/data/docker/jenkins_mount/workspace/maven-job 配置maven打包…

江科大STM32 下

目录 ADC数模转换器DMA直接存储器存取USART串口9-2 串口发送接受9-3 串口收发HEX数据包 I2CSPI协议10.1 SPI简介W25Q64简介10.3 SPI软件读写W25Q6410.4 SPI硬件读写W25Q64 BKP、RTC11.0 Unix时间戳11.1 读写备份寄存器BKP11.2 RTC实时时钟 十二、PWR12.1 PWR简介12.2 修改主频1…

Scratch优秀作品飞翔小鸟

程序说明&#xff1a;在无尽的划痕堆中飞驰而过随着你越来越多地飞进迷宫般的街区&#xff0c;平台变得越来越难。 演示视频 scratch飞翔小鸟 其实这就是一个类似像素小鸟的程序&#xff0c;只不过水管角色就地取材&#xff0c;使用scratch里面的积木图片拼成了水管&#xff0…

爬虫案例—抓取豆瓣电影的电影名称、评分、简介、评价人数

爬虫案例—抓取豆瓣电影的电影名称、评分、简介、评价人数 豆瓣电影网址&#xff1a;https://movie.douban.com/top250 主页截图和要抓取的内容如下图&#xff1a; 分析&#xff1a; 第一页的网址&#xff1a;https://movie.douban.com/top250?start0&filter 第二页的…

文献阅读:Large Language Models as Optimizers

文献阅读&#xff1a;Large Language Models as Optimizers 1. 文章简介2. 方法介绍 1. OPRO框架说明2. Demo验证 1. 线性回归问题2. 旅行推销员问题&#xff08;TSP问题&#xff09; 3. Prompt Optimizer 3. 实验考察 & 结论 1. 实验设置2. 基础实验结果 1. GSM8K2. BBH3.…

linux建立基本网站

网站需求&#xff1a; 1.基于域名[www.openlab.com]可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[www.openlab.com/student] 网站访问学生信息 [www.openlab.com/data]网站访问教学资…

微机原理常考填空以及注意事项

以下&#xff1a; 1&#xff0c;两条高位地址线未参加地址译码&#xff0c;则对应的地址范围它的容量是多少倍&#xff1f; 答&#xff1a;公式CPU的地址线&#xff08;假设16位&#xff09;&#xff08;它的低位地址线一般进入片内A0~A10&#xff0c;高位A11就是A、A12就是B、…

微信小程序(一)简单的结构及样式演示

注释很详细&#xff0c;直接上代码 涉及内容&#xff1a; view和text标签的使用类的使用flex布局水平方向上均匀分布子元素垂直居中对齐子元素字体大小文字颜色底部边框的宽和颜色 源码&#xff1a; index.wxml <view class"navs"><text class"active…

任务7:安装MySQL数据库

任务描述 知识点&#xff1a; MySQL数据库安装与使用 重 点&#xff1a; 基于CentOS系统&#xff0c;安装MySQL数据库 内 容&#xff1a; 安装MySQL数据库修改root用户密码 任务指导 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c…

【汽车销售数据】2015~2023年各厂商各车型的探索 数据分析可视化

数据处理的思路&#xff1a; 1 各表使用情况&#xff1a; 汽车分厂商每月销售表&#xff0c;该表主要分析展示top10销量的厂商销量、占比变化情况&#xff08;柱形图、饼图&#xff09;&#xff1b;中国汽车分车型每月销售量表&#xff0c;该表主要分析展示top20销量的车型销…

UML-顺序图

提示&#xff1a;用例图从参与者的角度出发&#xff0c;描述了系统的需求&#xff08;用例图&#xff09;&#xff1b;静态图定义系统中的类和对象间的静态关系&#xff08;类图、对象图和包图&#xff09;&#xff1b;状态机模型描述系统元素的行为和状态变化流程&#xff08;…

计算机体系结构基础复习

1. 计算机系统可划分为哪几个层次,各层次之间的界面是什么? 你认为这样划分层次的意义何在? 答&#xff1a; 计算机系统可划分为四个层次&#xff0c;分别是&#xff1a;应用程序、 操作系统、 硬件系统、 晶体管四个大的层次。 注意把这四个层次联系起来的三个界面。各层次…

css 怎么绘制一个带圆角的渐变色的边框

1&#xff0c;可以写两个样式最外面的div设置一个渐变的背景色。里面的元素使用纯色。但是宽高要比外面元素的小。可以利用里面的元素设置padding这样挡住部分渐变色。漏出来的渐变色就像边框一样。 <div class"cover-wrapper"> <div class"item-cover…

春节回家前,请一定给你的电脑装上KKView远程控制软件

马上春节了&#xff0c;电脑不能带回家&#xff0c;有时候要处理点意外的事情&#xff0c;怎么办&#xff1f;只要走之前&#xff0c;给你电脑装上KKView远程控制软件&#xff0c;就可以随时随地用手机或电脑控制你的工作电脑&#xff0c;远程办公、传文件、看摄像头都没问题。…

人脸识别为何老是不过?是什么原因导致的?

人脸识别可能无法通过的原因有很多&#xff0c;以下是可能的一些原因&#xff1a; 1. 非常规面部表情&#xff1a;如果你做出了与常规面部表情不同的表情&#xff0c;如张大嘴巴或瞪大眼睛等&#xff0c;可能会干扰人脸识别系统的准确性。 2. 光线条件&#xff1a;人脸识别系统…

30 3D导航栏

效果演示 实现了一个导航栏&#xff0c;其中包含了五个图标&#xff0c;每个图标都有一个悬浮的文字标签&#xff0c;当鼠标悬停在图标上时&#xff0c;文字标签会旋转并向上移动&#xff0c;同时底部会出现一个阴影效果。整个导航栏的背景颜色为浅灰色。 Code <ul><…

js(JavaScript)数据结构之堆(Heap)

什么是数据结构&#xff1f; 下面是维基百科的解释&#xff1a; 数据结构是计算机存储、组织数据的方式。数据结构意味着接口或封装&#xff1a;一个数据结构可被视为两个函数之间的接口&#xff0c;或者是由数据类型联合组成的存储内容的访问方法封装。 我们每天的编码中都会…

docker安装部署Elasticsearch(ES)以及相关配置

Elasticsearch简介 mysql用作持久化存储&#xff0c;ES用作检索 基本概念&#xff1a;index库>type表>document文档 index索引&#xff08;相当于MySQL的数据库&#xff09; 动词&#xff1a;相当于mysql的insert 名词&#xff1a;相当于mysql的db Type类型&#xff…

Spring Cloud整体架构解析

Spring Cloud整体架构 本文已收录至我的个人网站&#xff1a;程序员波特&#xff0c;主要记录Java相关技术系列教程&#xff0c;共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源&#xff0c;让想要学习的你&#xff0c;不再迷茫。 Spring Cloud的中文名我们就…