当前位置: 首页 > 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 自动获取单选题旧的选项列…...

怎么降维普AI率到30%以下?本科合格区间实战完整路径方案!

怎么降维普AI率到30%以下&#xff1f;本科合格区间实战完整路径方案&#xff01; 本科生维普 AI 率合格线 30%&#xff0c;比硕博严标准 15% 宽松一倍。但如果你的论文 AI 率 60% 重灾区&#xff0c;降到 30% 以下还是需要工具。你的真实情况是什么&#xff1f; 本科 4-5 万字论…...

Stagewise:基于Chromium的AI编程浏览器,重塑前端开发工作流

1. 项目概述&#xff1a;一个为开发者而生的“浏览器AI助手”新物种 如果你和我一样&#xff0c;每天的工作流是在浏览器、代码编辑器和终端之间反复横跳&#xff0c;那么你肯定也幻想过&#xff1a;要是能有一个工具&#xff0c;把这三者无缝融合在一起就好了。最近&#xff0…...

收藏必备!小白程序员轻松入门大模型:ReAct与Reflexion核心技术与实战应用

大语言模型&#xff08;LLM&#xff09;在复杂任务中存在事实幻觉、缺乏实时信息等局限。本文介绍ReAct和Reflexion两大提示技术框架&#xff0c;ReAct通过推理与行动协同&#xff0c;有效解决幻觉问题&#xff1b;Reflexion在ReAct基础上增加自我反思机制&#xff0c;形成闭环…...

为OpenClaw配置Taotoken实现高效AI智能体工作流

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 为OpenClaw配置Taotoken实现高效AI智能体工作流 OpenClaw 是一个流行的开源AI智能体框架&#xff0c;它允许开发者快速构建和编排复…...

内向技术人突破领导力瓶颈:从深度思考到战略沟通的进阶指南

1. 项目概述&#xff1a;内向工程师的“天花板”与破局之路 在技术圈子里待久了&#xff0c;你会发现一个有趣的现象&#xff1a;身边那些能写出精妙算法、搞定复杂架构的工程师&#xff0c;往往在茶水间的闲聊中显得沉默寡言&#xff0c;在大型会议上也更倾向于坐在后排。这并…...

寄生电感容易被忽略,却是电路不稳定的隐形元凶

调试电路板的时候&#xff0c;最让人抓狂的并不是那些明面上能查到文档的参数问题。示波器一抓波形&#xff0c;明明电源电压已经稳定&#xff0c;负载也没动&#xff0c;可偏偏就是有那种挥之不去的毛刺&#xff0c;幅度不大&#xff0c;频率不低&#xff0c;排查了半天才发现…...

从零打造蒸汽朋克辉光管时钟:驱动方案、定制管与系统集成实战

1. 项目概述&#xff1a;从零开始的蒸汽朋克辉光管时钟作为一个在电子制作和复古硬件领域折腾了十多年的老玩家&#xff0c;我始终对那些散发着温暖橘红色光芒的辉光管&#xff08;Nixie Tube&#xff09;情有独钟。它们不仅仅是时间的显示器&#xff0c;更像是一件连接过去与未…...

不止于下载:用Active-HDL给你的Lattice FPGA设计做个“体检”(功能仿真实战)

从功能仿真到可靠设计&#xff1a;Active-HDL在Lattice FPGA开发中的深度实践 当LED灯在你的FPGA开发板上如期闪烁时&#xff0c;那种成就感确实令人振奋。但作为经历过多次调试煎熬的工程师&#xff0c;我必须告诉你&#xff1a;能下载运行只是FPGA开发的起点&#xff0c;而非…...

PyQt-Fluent-Widgets导航组件深度解析:打造专业级侧边栏与选项卡界面

PyQt-Fluent-Widgets导航组件深度解析&#xff1a;打造专业级侧边栏与选项卡界面 【免费下载链接】PyQt-Fluent-Widgets A fluent design widgets library based on C Qt/PyQt/PySide. Make Qt Great Again. 项目地址: https://gitcode.com/gh_mirrors/py/PyQt-Fluent-Widget…...

MTKClient终极指南:解锁联发科设备的完整刷机与调试解决方案

MTKClient终极指南&#xff1a;解锁联发科设备的完整刷机与调试解决方案 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient 你是否曾经遇到过联发科设备变砖无法启动的困境&#xff1f;或者想…...