当前位置: 首页 > news >正文

(二十四)ATP应用测试平台——springboot集成fastdfs上传与下载功能

前言

本节内容我们主要介绍一下如何在springboot项目中集成fastdfs组件,实现文件的上传与下载。关于fastdfs服务中间键的安装过程,本节内容不做介绍。fastdfs是一个轻量级的分布式文件系统,也是我们文件存储中常常使用的组件之一,主要包括文件存储、文件同步、文件访问,实现了文件存储和负载均衡的问题。

正文

①引入fastdfs客户端的maven依赖

<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.27.2</version>
</dependency>

 ②在application.yml配置fastdfs的属性参数值

fdfs:so-timeout: 1501 # 超时时间connect-timeout: 601 # 连接超时时间tracker-list: # tracker地址:你的虚拟机服务器地址+端口(默认是22122)- 125.27.107.218:22122

 ③引入fastdfs客户端组件,交由spring管理

package com.ht.atp.plat.config;import com.github.tobato.fastdfs.FdfsClientConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDfsConfig {}

 ④创建springboot文件上传与下载的控制层接口FdfsRecordController.class

package com.ht.atp.plat.controller;import com.ht.atp.plat.common.Result;
import com.ht.atp.plat.service.FdfsRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;@Api(tags = {"文件管理"})
@RestController
@RequestMapping("/v1/fdfs/record")
public class FdfsRecordController {@Autowiredprivate FdfsRecordService fdfsRecordService;@ApiOperation(value = "文件上传")@PostMapping(value = "uploadFile")public Result<String> uploadFile(@ApiParam(name = "file", value = "上传的文件")@RequestParam(value = "file") MultipartFile file) {String url = fdfsRecordService.uploadFile(file);return Result.success(url);}@ApiOperation(value = "文件下载")@GetMapping(value = "downloadFile")public Result<String> downloadFile(@ApiParam(name = "url", value = "下载地址")@RequestParam(value = "url") String url) {String data = fdfsRecordService.downloadFile(url);return Result.success(data);}}

 ⑤创建springboot文件上传与下载的业务接口层FdfsRecordService.class

package com.ht.atp.plat.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.ht.atp.plat.entity.FdfsRecord;
import org.springframework.web.multipart.MultipartFile;public interface FdfsRecordService extends IService<FdfsRecord> {/*** 上传文件** @param file* @return*/String uploadFile(MultipartFile file);/*** 文件下载* @param url* @return*/String downloadFile(String url);
}

  ⑥创建springboot文件上传与下载的业务接口实现层FdfsRecordServiceImpl.class

package com.ht.atp.plat.service.impl;import cn.hutool.core.codec.Base64;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.ht.atp.plat.entity.FdfsRecord;
import com.ht.atp.plat.exception.BusinessException;
import com.ht.atp.plat.mapper.FdfsRecordMapper;
import com.ht.atp.plat.service.FdfsRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;@Service
public class FdfsRecordServiceImpl extends ServiceImpl<FdfsRecordMapper, FdfsRecord> implements FdfsRecordService {@Autowiredprivate FastFileStorageClient storageClient;@Overridepublic String uploadFile(MultipartFile file) {try {BufferedImage bufferedImage = ImageIO.read(file.getInputStream());if (bufferedImage == null) {throw new BusinessException("文件内容不合法,无法上传!");}String fileName = file.getOriginalFilename();String suffix = "";if (StringUtils.isNotEmpty(fileName)) {String[] splitFileName = fileName.split("\\.");if (splitFileName != null && splitFileName.length > 1) {suffix = splitFileName[splitFileName.length - 1];}}FdfsRecord fdfsRecord = new FdfsRecord();fdfsRecord.setModifyTime(LocalDateTime.now());fdfsRecord.setCreateTime(LocalDateTime.now());fdfsRecord.setSuffixName(suffix);fdfsRecord.setName(fileName);StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), suffix, null);fdfsRecord.setUrl(storePath.getFullPath());baseMapper.insert(fdfsRecord);return storePath.getFullPath();} catch (Exception e) {throw new BusinessException("文件上传服务异常,请稍后重试!");}}@Overridepublic String downloadFile(String url) {String group = url.substring(0, url.indexOf("/"));String path = url.substring(url.indexOf("/") + 1);DownloadByteArray byteArray = new DownloadByteArray();byte[] data = this.storageClient.downloadFile(group, path, byteArray);String encodeData = Base64.encode(data);return encodeData;}
}

⑦创建springboot文件资源信息存储的持久化层FdfsRecordMapper.class,实现文件资源信息的持久化存储

package com.ht.atp.plat.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ht.atp.plat.entity.FdfsRecord;public interface FdfsRecordMapper extends BaseMapper<FdfsRecord> {}

⑧创建springboot文件资源信息存储的持久化层FdfsRecordMapper.xml,实现文件资源信息的持久化存储

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ht.atp.plat.mapper.FdfsRecordMapper"></mapper>

 ⑨创建springboot文件资源信息存储的实体类FdfsRecord.class

package com.ht.atp.plat.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;import java.io.Serializable;
import java.time.LocalDateTime;@Getter
@Setter
@TableName("fdfs_record")
@ApiModel(value = "FdfsRecord对象", description = "")
public class FdfsRecord implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty("主键ID")@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;@ApiModelProperty("业务ID")@TableField("business_id")private String businessId;@ApiModelProperty("服务名称")@TableField("service_name")private String serviceName;@ApiModelProperty("文件名称")@TableField("name")private String name;@ApiModelProperty("文件地址")@TableField("url")private String url;@ApiModelProperty("后缀名称")@TableField("suffix_name")private String suffixName;@ApiModelProperty("创建时间")@TableField("create_time")private LocalDateTime createTime;@ApiModelProperty("创建人")@TableField("create_user")private String createUser;@ApiModelProperty("修改时间")@TableField("modify_time")private LocalDateTime modifyTime;@ApiModelProperty("修改人")@TableField("modify_user")private String modifyUser;}

⑩ 使用swagger测试文件上传功能

 ⑪使用swagger测试文件下载功能

结语

通过至此,关于springboot集成fastdfs上传与下载功能到这里就结束了,下期见。。。

相关文章:

(二十四)ATP应用测试平台——springboot集成fastdfs上传与下载功能

前言 本节内容我们主要介绍一下如何在springboot项目中集成fastdfs组件&#xff0c;实现文件的上传与下载。关于fastdfs服务中间键的安装过程&#xff0c;本节内容不做介绍。fastdfs是一个轻量级的分布式文件系统&#xff0c;也是我们文件存储中常常使用的组件之一&#xff0c…...

linux好用命令+vs快捷键

linux好用命令 功能指令跳转到vim界面的最后一行shift键g复制当前路径下所有文件和目录&#xff08;加-r才行&#xff09;到target目录cp -r * /home/target删除指定文件rm -rf test.txt文件重命名&#xff08;-i交互式提示&#xff09;mv -i file1 file2移动某个内容&#xf…...

Git 构建分布式版本控制系统

版本控制概念Gitlab部署1.版本控制概念 1.1分类 &#xff08;一&#xff09;1 本地版本控制系统&#xff08;传统模式&#xff09; &#xff08;二&#xff09;2 集中化的版本控制系统 CVS、Subversion&#xff08;SVN&#xff09; &#xff08;三&#xff09;3 分布式…...

Day891.一主多从的切换正确性 -MySQL实战

一主多从的切换正确性 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于一主多从的切换正确性的内容。 在切换任务的时候&#xff0c;要先主动跳过这些错误&#xff0c;通过主动跳过一个事务或者直接设置跳过指定的错误&#xff0c;用GTID解决找同步位点的问题 大多…...

【论文笔记】图像修复Learning Joint Spatial-Temporal Transformations for Video Inpainting

论文地址&#xff1a;https://arxiv.org/abs/2007.10247 源码地址&#xff1a;GitHub - researchmm/STTN: [ECCV2020] STTN: Learning Joint Spatial-Temporal Transformations for Video Inpainting 一、项目介绍 当下SITA的方法大多采用注意模型&#xff0c;通过搜索参考帧…...

代码随想录算法训练营第二天 | 977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵II、总结

打卡第二天&#xff0c;认真做了两道题目&#xff0c;顶不住了好困&#xff0c;明天早上练完车回来再重新看看。 今日任务 第一章数组 977.有序数组的平方209.长度最小的子数组59.螺旋矩阵II 977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每…...

Python pickle模块:实现Python对象的持久化存储

Python 中有个序列化过程叫作 pickle&#xff0c;它能够实现任意对象与文本之间的相互转化&#xff0c;也可以实现任意对象与二进制之间的相互转化。也就是说&#xff0c;pickle 可以实现 Python 对象的存储及恢复。值得一提的是&#xff0c;pickle 是 python 语言的一个标准模…...

【C++】C/C++内存管理

文章目录1. C/C内存分布2. C语言当中的动态内存管理3. C 内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型4. operator new 和operator delete 函数5. new和delete的实现原理5.1 内置类型5.2 自定义类型6. 定位new表达式(placement-new)7. 常见面试题7.1 …...

【测试】自动化测试02

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录前言 回顾 预告一、常见的元素操作1. 输入文本sendKeys()2. 点击click3. 提交submit&#xff08;通过回车键提交&#xff09;4. 清除clear5. 获取文本getText()6. 获取属性对应的值getAttribute()7. 查看title和ur…...

Python空间分析| 02 利用Python计算空间局部自相关(LISA)

局部空间自相关 import esda import numpy as np import pandas as pd import libpysal as lps import geopandas as gpd import contextily as ctx import matplotlib.pyplot as plt from geopandas import GeoDataFrame from shapely.geometry import Point from pylab im…...

idea快捷编码:生成for循环、主函数、判空非空、生成单例方法、输出;自定义快捷表达式

前言 idea可根据输入的简单表达式进行识别&#xff0c;快速生成语句 常用的快捷编码&#xff1a;生成for循环、主函数、判空非空、生成单例方法、输出 自定义快捷表达式 博客地址&#xff1a;芒果橙的个人博客 【http://mangocheng.com】 一、idea默认的快捷表达式查看 Editor…...

【Spring】@Value注入配置文件 application.yml 中的值失败怎么办

本期目录一、 问题背景二、 问题原因三、 解决方法一、 问题背景 今天碰到的问题是用 Value 注解无法注入配置文件 application.yml 中的配置值。 检查过该类已经交给 Spring 容器管理了&#xff0c;即已经在类上加了 Configuration 和 ConfigurationProperties(prefix &quo…...

CleanMyMac清理工具软件功能优势介绍

CleanMyMac更新最新版本x4.12&#xff0c;完美适配新版系统macOS10.14&#xff0c;拥有全新的界面。CleanMyMac可以让您安全、智能地扫描和清理整个系统&#xff0c;删除大型未使用的文件&#xff0c;减少iPod库的大小&#xff0c;最精确的应用程序卸载&#xff0c;卸载不必要的…...

【面试题】对JS中的事件冒泡、事件捕获、事件委托的理解

大厂面试题分享 面试题库后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库DOM事件流&#xff08;event flow &#xff09;存在三个阶段&#xff1a;事件捕获阶段、处于目标阶段、事件冒泡阶段。Dom标准事件流的触发的先…...

SAP 理解合并会计报表

随着企业集团的发展&#xff0c;集团内部会出现越来越多的公司&#xff1b;复杂的公司结构和复杂的集团内业务&#xff0c;使得集团内部管理困难重重&#xff0c;信息渠道严重失灵。除了内部管理的需要&#xff0c;企业还有义务向相关方提供详细的和及时的信息。ERP中的合并会计…...

Ubuntu 命令常用命令——定时启动程序

crontab -e 语法 crontab[ -u user ] file或 crontab[ -u user ] { -l | -r | -e }说明: crontab是用来让使用者在固定时间或固定间隔执行程序之用&#xff0c;换句话说&#xff0c;也就是类似使用者的时程表。 -U Lser 是指设定指定user的时程表&#xff0c;这个前提是你必…...

笔试题(十三):走迷宫

# 描述 # 定义一个二维数组 N*M &#xff0c;如 5 5 数组下所示&#xff1a; # int maze[5][5] { # 0, 1, 0, 0, 0, # 0, 1, 1, 1, 0, # 0, 0, 0, 0, 0, # 0, 1, 1, 1, 0, # 0, 0, 0, 1, 0,}; # 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0c;0表示可以走的路&#…...

Gradle相关的知识学习

这里有一套博客文章写的比较通俗易懂&#xff1a;https://www.jianshu.com/p/8e1ddd19083a...

SpringMVC的工作原理

SpringMVC的工作原理流程图 SpringMVC流程 1、 用户发送请求至前端控制器DispatcherServlet。 2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找)&#xff0c;生成处理器对象及处理器拦截…...

问卷数据分析流程

文章目录一、数据合并1. 读取数据2. 数据预览二、数据清洗1. 检验ID是否重复&#xff0c;剔除ID重复项2. 剔除填写时间小于xx分钟的值3.处理 量表题 一直选一个选项的问题三、数据清洗1.1 将问卷单选题的选项code解码&#xff0c;还原成原来的选项1.2 自动获取单选题旧的选项列…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...