【SpringBoot整合系列】SpringBoot整合FastDFS(二)
目录
- SpringBoot整合FastDFS
- Java客户端/依赖
- 常用api接口解释
- 1.uploadFile
- 参数
- 返回值
- 2.uploadSlaveFile
- 参数
- 返回值
- 3.getMetadata
- 参数
- 返回值
- 4.overwriteMetadata
- 参数:
- 返回值:无
- 5.mergeMetadata
- 参数:
- 返回值:无
- 6.queryFileInfo
- 参数:
- 返回值
- 7.deleteFile
- 参数:
- 返回值:无
- 8.downloadFile
- 参数
- 返回值
- 9.downloadFile
- 参数
- 返回值
- 代码测试
- yml配置
- 工具类
- 上传
- Controller
- 测试
- 下载
- Controller
- 测试
SpringBoot整合FastDFS
Java客户端/依赖
<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.27.2</version></dependency>
常用api接口解释
1.uploadFile
uploadFile(String groupName, InputStream inputStream, long fileSize, String fileExtName)
参数
- groupName:上传文件所属的组名。
- inputStream:输入流对象,指向要上传的文件内容。
- fileSize:上传文件的大小,单位为字节。
- fileExtName:上传文件的扩展名。
返回值
返回值:一个 StorePath 对象,其中封装文件的路径和 store 节点的地址。
2.uploadSlaveFile
uploadSlaveFile(String groupName, String masterFilename, InputStream inputStream, long fileSize, String prefixName, String fileExtName)
参数
- groupName:文件上传到的组名。
- masterFilename:主文件的名称。
- inputStream:从文件的输入流对象。
- fileSize:上传从文件的大小,单位为字节。
- prefixName: 从文件名前缀
- fileExtName:从文件的扩展名
返回值
返回值:一个 StorePath 对象,表示成功上传后从文件存储的路径信息。
3.getMetadata
getMetadata(String groupName, String path)
参数
- groupName:文件所属的分组名。
- path:文件的在 FastDFS 存储中真实的路径。
返回值
返回值:Set 集合,其中包含多组 metadata 信息。每一条 metadata 是 k-v 形式的键值对。如果没有找到对应的 metadata 信息,则返回一个空的集合。
4.overwriteMetadata
overwriteMetadata(String groupName, String path, Set
参数:
- groupName:文件所属的分组名。
- path:文件在 FastDFS 存储中真实的路径。
- metaDataSet:要覆盖的新的 metadata 集合。
返回值:无
5.mergeMetadata
mergeMetadata(String groupName, String path, Set
参数:
- groupName:文件所属的分组名。
- path:文件在 FastDFS 存储中真实的路径。
- metaDataSet:待合并的metadata集合。
返回值:无
6.queryFileInfo
queryFileInfo(String groupName, String path)
参数:
- groupName:文件所属的组名。
- path:文件在 FastDFS 存储中真实的路径。
返回值
返回值:一个 FileInfo 对象,包含了文件的元数据信息。
7.deleteFile
deleteFile(String groupName, String path)
参数:
- groupName:文件所属的组名。
- path:文件在 FastDFS 存储中真实的路径。
返回值:无
8.downloadFile
downloadFile(String groupName, String path, DownloadCallback callback)
参数
- groupName:文件所属的组名。
- path:文件在 FastDFS 存储中真实的路径。
- callback:下载回调接口对象。
返回值
返回值:一个泛型值对象 T,表示经过回调方法处理后的结果。
9.downloadFile
downloadFile(String groupName, String path, long fileOffset, long fileSize, DownloadCallback callback)
参数
- groupName:文件所属的组名。
- path:文件在 FastDFS 存储中真实的路径。
- fileOffset:文件偏移量,从哪个地方开始下载。
- fileSize:要下载的文件大小。
- callback:下载回调接口对象。
返回值
返回值:一个泛型值对象 T,表示经过回调方法处理后的结果。
代码测试
yml配置
fdfs:
# 超时时间connect_timeout: 5000# 读取时间so_timeout: 30000# 服务地址列表tracker-list: 192.168.29.31:22122
# 解决限制文件大小
spring:servlet:multipart:max-request-size: 1TBmax-file-size: 1TB
工具类
package com.zjl.util;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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;/*** @author: zjl* @datetime: 2024/4/7* @desc:*/
@Component
public class FastdfsUtil {@Resourceprivate FastFileStorageClient storageClient;/*** 上传** @param file* @return*/public String upload(MultipartFile file) {// 获取文件名String filename = file.getOriginalFilename();// 得到文件扩展名String extName = filename.substring(filename.lastIndexOf(".") + 1);StorePath storePath = null;try {// 上传storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);// 这个getFullPath是fastdfs返回的id,可通过这个实现图片浏览、视频播放、文件下载等操作return storePath.getFullPath();} catch (IOException e) {throw new RuntimeException(e);}}/*** 下载文件(写二进制流)* @param path* @return*/public ResponseEntity<byte[]> download(String fileName ,String path,HttpServletRequest request) throws Exception {StorePath storePath = StorePath.parseFromUrl(path);String substring = path.substring(path.lastIndexOf("."));byte[] data = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());fileName = this.getFilename(request,fileName);HttpHeaders httpHeaders = new HttpHeaders();// 设置下载响应类型以及文件名httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);httpHeaders.setContentDispositionFormData("attachment",fileName+substring );return new ResponseEntity<>(data,httpHeaders, HttpStatus.OK);}//解决中文下载问题public String getFilename(HttpServletRequest request, String filename) throws Exception {//ie浏览器的编码格式String[] IEBrowserWords = {"MSIE","Trident","Edge"};String userAgent = request.getHeader("User-Agent");for (String ieBrowserWord : IEBrowserWords) {if(userAgent.contains(ieBrowserWord)){return URLEncoder.encode(filename,"UTF-8");}}//其他浏览器就采用这种编码格式return new String(filename.getBytes("UTF-8"),"ISO-8859-1");}
}
上传
Controller
package com.zjl.controller;import com.zjl.util.FastdfsUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;/*** @author: zjl* @datetime: 2024/4/7* @desc:*/
@RestController
public class MyFileController {@Resourceprivate FastdfsUtil fastdfsUtil;@PostMapping("/upload")public String upload(MultipartFile file){return fastdfsUtil.upload(file);}
}
测试
直接访问这个地址:http://192.168.29.31:8888/group1/M00/00/00/wKgdH2YSNj2ABnBCAAEQeS5bVeM384.jpg
下载
Controller
@GetMapping("/download")public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {//假设这是从其他业务层获取的文件路径String filePath = "group1/M00/00/00/wKgdH2YSNj2ABnBCAAEQeS5bVeM384.jpg";String fileName = "Spring权限管理";return fastdfsUtil.download(fileName,filePath,request);}
测试
相关文章:

【SpringBoot整合系列】SpringBoot整合FastDFS(二)
目录 SpringBoot整合FastDFSJava客户端/依赖常用api接口解释1.uploadFile参数返回值 2.uploadSlaveFile参数返回值 3.getMetadata参数返回值 4.overwriteMetadata参数:返回值:无 5.mergeMetadata参数:返回值:无 6.queryFileInfo参…...

L2-2 巴音布鲁克永远的土(二分+并查集)
思路:我们可以二分答案,然后判断当前答案合不合理。 对于判断答案合理,可以用并查集,看mid能否把所有检查点连进一个集合中,枚举每个结点,如何当前结点周围的四个方向可以连的话,就加进同一个集…...

Spring Cloud学习笔记:Eureka简介,Eureka简单样例
这是本人学习的总结,主要学习资料如下 - 马士兵教育 [TOC](目录)1、Eureka 1.1、架构 Eureka是SpringCloud Nexflix的核心子模块,其中包含Server和Client。 Server提供服务注册,存储所有可用服务节点。 Client用于简化和Server的通讯复杂…...

【漏洞复现】WordPress Welcart 任意文件读取漏洞(CVE-2022-4140)
0x01 产品简介 Welcart 是一款免费的 WordPress 电子商务插件。Welcart 具有许多用于制作在线商店的功能和自定义设置。您可以轻松创建自己的原始在线商店。 0x02 漏洞概述 Welcart存在任意文件读取漏洞,未授权的攻击者可以通过该漏洞读取任意文件,获…...
快速排序:深入解析其原理、实现与性能特性
快速排序,以其名字所示,是一种追求速度的高效排序算法。作为分治法在排序问题上的典型应用,快速排序凭借其平均情况下近乎理想的O(n log n)时间复杂度和简洁的实现逻辑,在实际编程与数据处理中占据着重要地位。本篇博客将详细解析…...

一文看懂Mac地址
一、Mac地址是什么? 虽然IP地址已经成为一个家喻户晓的术语,但还有一个同样重要的数字标识符值得我们关注——MAC地址。在本文中,我们旨在阐明网络中这个经常被忽视的方面。加入我们,深入研究 MAC 地址的世界,了解它们…...
2024.4.10作业
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } //显示时间 void Widget::timerEvent(QTimerEvent *e) { QT…...
python - Django创建项目
项目运行命令 根目录下运行命令: python manage.py runserver win环境创建项目 直接使用 Pycharm 创建项目 在 cmd 或 Linux 命令行环境下创建 Django 项目 django-admin startproject mysite 这样就会在当前目录下创建一个叫做 mysite 的Django项目。 可以看到Djang…...
WPF —— 动画缩放变换
ScaleTransform:在二维x-y坐标系统内缩放对象; 在故事板中依赖的属性为RenderTransform.ScaleX或RenderTransform.ScaleY,这要根据你要沿哪个轴进行缩放,X代表x轴,Y代表y轴; key属性当我们使用静态资源访问时候--> <!--TargetType"{x:Type Button} 直接应用…...

SQL注入---盲注
文章目录 目录 一.盲注概述 布尔盲注: 时间盲注: 一.盲注概述 注是一种SQL注入攻击的形式,在这种攻击中,攻击者向目标应用程序发送恶意注入代码,然后通过观察应用程序的响应来推断出数据库中的信息。与常规的SQL注入…...

PlanUML和Mermaid哪个好?
引言 在当今信息化快速发展的时代,数据可视化和图表工具不仅对于程序员,也对于非技术背景的人士至关重要。绘图工具可以帮助我们更好地理解和表达复杂的概念或数据流。PlantUML和Mermaid是两款被广泛使用的绘图语言,它们都能够通过简洁的文本…...

leetcode 343. 整数拆分
题目 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 10 输出: 36 解释: 1…...

【MATLAB源码-第180期】基于matlab的PTS,SLM,CPFilter三种降低OFDM系统的PAPR仿真。
操作环境: MATLAB 2022a 1、算法描述 1. 限幅和滤波(Clipping and Filtering) 原理简介 限幅和滤波是一种基础且直观的方法,用于降低OFDM信号的PAPR。在限幅阶段,信号的幅度在达到设定阈值时会被削减,…...

学透Spring Boot — 004. Spring Boot Starter机制和自动配置机制
如果你项目中一直用的是 Spring Boot,那么恭喜你没有经历过用 Spring 手动集成其它框架的痛苦。 都说 Spring Boot 大大简化了 Spring 框架开发 Web 应用的难度,这里我们通过配置 Hibernate 的两种方式来深刻体会这一点: 使用 Spring 框架集…...

面试算法-170-二叉树的最大深度
题目 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3 解 class Solution {public int maxDepth(TreeNod…...

【数据结构】哈希
文章目录 1. 哈希概念2. 哈希冲突3. 哈希函数4. 哈希冲突解决4.1 闭散列4.2 开散列 unordered 系列的关联式容器之所以效率比较高,是因为其底层使用了哈希结构。 1. 哈希概念 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系ÿ…...

Kubernetes(k8s)监控与报警(qq邮箱+钉钉):Prometheus + Grafana + Alertmanager(超详细)
Kubernetes(k8s)监控与报警(qq邮箱钉钉):Prometheus Grafana Alertmanager(超详细) 1、部署环境2、基本概念简介2.1、Prometheus简介2.2、Grafana简介2.3、Alertmanager简介2.4、Prometheus …...

STM32-04基于HAL库(CubeMX+MDK+Proteus)中断案例(按键中断扫描)
文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式,生成代码四、MDK打开生成项目,编写HAL库的按键检测代码五、运行仿真程序,调试代码 一、功能需求分析 在完成GPIO输入输出案例之后,开始新的功能…...

第十五篇:Mybatis
文章目录 一、什么是MyBatis二、Mybatis入门案例三、配置SQL提示四、数据库连接池四、lombok五、mybatis基础操作5.1 根据id删除5.2 预编译SQL5.3 新增员工5.4 更新员工5.5 查询员工(用于页面回显)5.6 条件查询 七、XML映射文件八、动态SQL8.1 if语句8.2…...

【MacBook系统homebrew镜像记录】
安装 使用Homebrew 国内源安装脚本,贼方便: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"切换至清华大学镜像源: 命令合并: 分别切换了 brew.git、 homebrew-core.git、 homebrew-…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

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