四、SpringBoot操作FastDFS实现文件上传(基本版)
由GitHub大牛tobato在原作者YuQing与yuqih发布的JAVA客户端基础上进行了大量重构工作,并于GitHub上发布了FastDFS-Client1.26.5。
主要特性
- 对关键部分代码加入了单元测试,便于理解与服务端的接口交易,提高接口质量
- 将以前对byte硬解析风格重构为使用对象+注解的形式,尽量增强了代码的可读性
- 支持对服务端的连接池管理
- 支持上传图片时候检查图片格式,并且自动生成缩略图
- 在SpringBoot当中自动导入依赖
1、创建springboot项目(2.7.0),导入FastDFS依赖jar
<dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.26.5</version> </dependency>
2、添加配置
####分布式文件系统配置########### fdfs: so-timeout: 1500 connect-timeout: 600 thumb-image: #缩略图生成参数 width: 150 height: 150 tracker-list: #TrackerList参数,支持多个 - 192.168.66.100:22122 # - 192.168.66.101:22122
3、编写测试类实现文件上传和文件下载
package com.zj; 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.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import java.io.*; @SpringBootTest class FastdfsApplicationTests { //通过FastDFS的客户端对象完成对文件系统的操作 @Resource private FastFileStorageClient fastFileStorageClient; //测试上传文件 @Test public void upload() throws FileNotFoundException { //1.先读取本地文件 File file = new File("D:\\aaa.jpg"); //2.创建传输文件输入流 FileInputStream fileInputStream = new FileInputStream(file); //3.文件上传 /* * 参数一:文件输入流 * 参数二:文件大小 * 参数三:文件拓展名 * 参数四:描述文件的元数据(指定文件上传的位置) */ StorePath storePath = fastFileStorageClient.uploadFile(fileInputStream, file.length(), "jpg", null); //4.将卷名和文件名一起打印 System.out.println("上传文件的地址:"+storePath.getFullPath()); System.out.println("文件卷名:"+storePath.getGroup()); System.out.println("文件名:"+storePath.getPath()); } //文件下载 @Test public void download() throws IOException { //1.下载文件 /* * 参数一:文件处于存储节点的卷名 * 参数二:文件在存储节点的文件名 * 参数三:下载的回调函数 */ byte[] downloadFile = fastFileStorageClient.downloadFile("group1", "M00/00/00/wKhCZGS2WGaAYKOuADcAPt_yJDw957.jpg", new DownloadByteArray()); //2.创建文件输出流,并指定文件下载的位置 FileOutputStream fileOutputStream = new FileOutputStream("d:\\aaa.jpg"); //3.将文件输出流写文件到磁盘 fileOutputStream.write(downloadFile); //4.刷新 fileOutputStream.flush(); //5.关闭流 fileOutputStream.close(); } }
五、spring boot整合FastDFS实现文件上传(完整版)
1、引入Thymeleaf视图解析器和文件上传客户端对象
<!--fastdfs--> <dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.26.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
注意:
使用wangeditor富文本编辑器的前提是引入Thymeleaf模板。
2、通过CDN在前端页面引入wangEditor富文本编辑器
<script type="text/javascript" src="https://unpkg.com/wangeditor/dist/wangEditor.min.js"></script>
3、创建编辑器基本骨架
<div id="div1"> <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p> </div> <script type="text/javascript"> const E = window.wangEditor; const editor = new E('#div1') editor.create(); </script>
4、创建文件上传的Controller控制器
package com.zj.controller; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.service.FastFileStorageClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; @RestController public class uploadController { @Resource private FastFileStorageClient fastFileStorageClient; //图片上传 @PostMapping("/upload") public void upload(MultipartFile file) throws IOException { //1.判断文件是否为空 if(file != null){ //2.获取上传的图片的名字 String originalFilename = file.getOriginalFilename(); //3.获取上传的图片的扩展名 String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); //4.上传图片 StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), suffix, null); System.out.println("上传的文件的路径:"+storePath.getFullPath()); //5.上传的文件路径需要保存到数据库中 //…… } } }
文件上传的请求方式必须是post
5、完整的index.html页面
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>文件上传</title> <script type="text/javascript" src="https://unpkg.com/wangeditor/dist/wangEditor.min.js"></script> </head> <body> <div id="div1"> <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p> </div> <script type="text/javascript"> const E = window.wangEditor; const editor = new E('#div1'); //指定文件上传的服务路径 editor.config.uploadImgServer = "/upload"; //文件参数名 editor.config.uploadFileName = "file"; //限制文件上传的大小和类型 2M editor.config.uploadImgMaxSize = 2 * 1024 * 1024; //文件上传的类型 editor.config.uploadImgAccept = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']; editor.create(); </script> </body> </html>
6、启动项目,上传图片即可
六、FastDFS整合Nginx
Nginx服务器是一个高性能的web服务器与反向代理服务器。
FastDFS集成Nginx的2个原因
- 为分布式文件系统提供Http服务支持
通过Nginx的web服务代理访问分布式文件系统的存储节点,从而实现通过http请求访问存储节点资源。
注意:
src 属性值图像文件的 URL。也就是引用该图像的文件的的绝对路径或相对路径。
2.解决复制延迟问题
由于FastDFS的同卷的存储节点之间需要同步,当文件尚未同步完成时,访问请求到达改节点,获取的数据将是未同步完的不完整数据,即为复制延迟问题。通过Nginx检测请求的存储节点的数据,若该存储节点的数据尚未同步完成,则将请求转发至数据的原存储节点,从而解决复制延迟问题。
环境搭建
下载Fastdfs的Nginx模块包
#选择安装位置 cd /usr/local #下载文件(或者使用本文章已经下载好的文件) wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.22.tar.gz #解压文件 tar -zxvf V1.22.tar.gz
在ginx-1.20.2目录下安装Nginx依赖文件
yum install -y gcc gcc-c++ zlib zlib-devel openssl openssl-devel pcre pcre-devel gd-devel epel-release
配置Nginx服务器
#建立Makefile文件,检查Linux系统环境以及相关的关键属性。添加fastdfs-nginx-module-1.22模块到nginx ./configure --add-module=/usr/local/fastdfs-nginx-module-1.22/src/ #编译项目,主要将gcc源代码编译成可执行的目标文件 make #根据上一步骤编译完成的数据安装到预定的目录中。之前安装过ngxin的话不需要再安装 make install
注意:
- –add-module:为nginx添加一个fastdfs-nginx-module模块,值为该模块在当前系统的路径
- –prefix:指定nginx安装位置
将Fastdfs软件包里面的http.conf和mime.types拷贝到/etc/fdfs目录下
cp /usr/local/fastdfs-6.06/conf/mime.types /etc/fdfs/ cp /usr/local/fastdfs-6.06/conf/http.conf /etc/fdfs/
配置Nginx的fastdfs模块,并编辑文件
#拷贝文件 [root@localhost opt]cp /usr/local/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf /etc/fdfs/ [root@localhost fdfs] vim mod_fastdfs.conf #保存日志目录 base_path=/data/fastdfs/storage #tracker 服务器的 IP 地址以及端口号 tracker_server=192.168.66.100:22122 #文件url中是否有group 名 url_have_group_name = true #存储路径 store_path0=/data/fastdfs/storage group_count = 1 #设置组的个数 #然后在末尾添加分组信息,目前只有一个分组,就只写一个 [group1] group_name=group1 storage_server_port=23000 store_path_count=1 store_path0=/data/fastdfs/storage
配置Nginx
server { listen 80; server_name localhost; location ~ /group[1-3]/M00 { alias /data/fastdfs/storage/data; ngx_fastdfs_module; } # 根目录下返回403 location = / { return 403; } # log file access_log logs/img_access.log access; }
启动Ningx服务
# 进入sbin目录 [root@tracker nginx]# cd sbin/ # 启动服务 -c:指定配置文件 [root@tracker sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf
查看服务启动情况
[root@tracker sbin]# ps -ef | grep nginx
启动追踪服务与存储节点服务
[root@tracker sbin]# fdfs_trackerd /etc/fdfs/tracker.conf start [root@tracker sbin]# fdfs_storaged /etc/fdfs/storage.conf start
上传图片测试
将图片上传至linux系统后,使用指令上传至分布式文件系统
[root@localhost /]# fdfs_upload_file /etc/fdfs/client.conf pdx.jpg group1/M00/00/00/wKhCZGS6zneAUxGKAANsTCZQKGY401.jpg
通过浏览器远程访问
http://192.168.66.100/group1/M00/00/00/wKhCZGS6zneAUxGKAANsTCZQKGY401.jpg