本篇文章为你整理了FastDFS(fastdfs集群搭建)的详细内容,包含有fastdfs部署 fastdfs集群搭建 fastdfs上传文件 fastdfs启动命令 FastDFS,希望能帮助你了解 FastDFS。
常见的分布式文件系统有:FastDFS、GFS、HDFS、Lustre 、Ceph 、GridFS 、mogileFS、TFS 等。
FastDFS 是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用 C 语言开发,由阿里巴巴开发并开源。
FastDFS 对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载、文件删除)等,解决了大容量文件存储的问题,特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等等。
FastDFS 充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
客户端通常指我们的程序,比如我们的 Java 程序去连接 FastDFS、操作 FastDFS,那我们的 Java 程序就是一个客户端,FastDFS 提供专有 API 访问,目前提供了 C、Java 和 PHP 几种编程语言的 API,用来访问 FastDFS 文件系统。
跟踪器(tracker)主要做调度工作,在内存中记录集群中存储节点 storage 的状态信息,是前端 Client 和后端存储节点 storage的枢纽。因为相关信息全部在内存中,Tracker server 的性能非常高,一个较大的集群(比如上百个group)中有3台就足够了。
存储节点(storage)用于存储文件,包括文件和文件属性(meta data)都保存到存储服务器磁盘上,完成文件管理的所有功能:文件存储、文件同步和提供文件访问等。
资源下载地址(或百度云盘直取):https://github.com/happyfish100
资源介绍:
fastdfs-6.08.tar.gz:FastDFS 的安装包(只能在 Linux 上安装)
fastdfs-client-java-1.28.zip:FastDFS 的 Java 客户端源代码
fastdfs-nginx-module-1.22.zip:FastDFS-Nginx 的扩展模块
libfastcommon-1.0.56.tar.gz:FastDFS 的公共函数库(Linux 上安装)
FastDFS 安装
FastDFS 没有 Windows 版本,不能在 Windows 下使用。
FastDFS 需要安装部署在 Linux 环境下。
安装 gcc、libevent、libevent-devel 前置依赖
yum install gcc libevent libevent-devel -y
将 FastDFS 的安装包 fastdfs-6.08.tar.gz 和 FastDFS 的公共函数库 libfastcommon-1.0.56.tar.gz 上传到 /home/soft/ 下
至此 FastDFS 安装完成!
所有编译出来的文件存放在 /usr/bin 目录下(放在 /usr/bin 下的命令,我们可在任何地方使用,不用切目录)
所有配置文件存放在 /etc/fdfs 目录下,如下:(后面会使用到这些配置文件)
client.conf
storage.conf
storage_ids.conf
tracker.conf
注意:还需要将 /home/soft/fastdfs-6.08/conf/下的 http.conf 和 mime.types 两个文件拷贝到 /etc/fdfs/ 目录下;
后期程序会使用到这两个文件,避免报错;
cp /home/soft/fastdfs-6.08/conf/http.conf /etc/fdfs/
cp /home/soft/fastdfs-6.08/conf/mime.types /etc/fdfs/
如果你使用的安装版本中/etc/fdfs下的配置文件有类似 .sample 扩展名,则其为示例配置文件,需要去掉 .sample 后缀才能生效,这点需要注意下。
配置 tracker.conf 文件:(跟踪器配置文件)
找到 base_path 参数,配置 tracker 存储数据的目录并手动创建:(需要确保该目录存在,目录需要我们手动创建好)
base_path:配置 tracker 存储数据的目录
base_path = /opt/fastdfs/tracker
配置 storage.conf 文件:(存储节点配置文件)
找到 base_path 参数,配置 storage 存储数据的目录并手动创建:(需要确保该目录存在,目录需要我们手动创建好)
base_path:配置 storage 存储数据的目录
path_path = /opt/fastdfs/storage
找到 store_path0 参数,配置 storage 的磁盘存放路径,即真正存放文件的目录:(需确保该目录存在,需我们手动创建好)
store_path0:真正存放文件的目录
store_path0 = /opt/fastdfs/storage/files
找到 tracker_server 参数,配置当前存储节点的跟踪器地址:(只需要配置 IP 即可,端口不要改动)
tracker_server:注册当前存储节点的跟踪器地址
tracker_server = 192.168.154.129:22122
将在 Windows 中配置完成并保存的 tracker.conf 和 storage.conf 两个文件上传到 /etc/fdfs目录下,并覆盖原文件;
上传并覆盖的命令:rz -y
fdfs_trackerd config_file [start stop restart]
fdfs_storaged config_file [start stop restart]
在确保需要手动创建的目录存在的情况下,分别执行下列命令启动 FastDFS:(不加 start 默认是启动)
fdfs_trackerd /etc/fdfs/tracker.conf
fdfs_storaged /etc/fdfs/storage.conf
ps -efgrep fdfs 查看相关进程,是否启动成功
FastDFS 重启
分别执行下列命令重启 FastDFS:
fdfs_trackerd /etc/fdfs/tracker.conf restart
fdfs_storaged /etc/fdfs/storage.conf restart
ps -efgrep fdfs 查看相关进程,是否重启成功
FastDFS 关闭
分别执行下列命令关闭 FastDFS:(其实也可使用 kill 关闭,但为了防止上传文件中数据丢失,不建议使用 kill 方式)
fdfs_trackerd /etc/fdfs/tracker.conf stop
fdfs_storaged /etc/fdfs/storage.conf stop
ps -efgrep fdfs 查看相关进程,是否成功关闭
FastDFS 测试
此处示例的上传下载操作其实开发中用不到,主要是感受下 FastDFS 的执行;重点是上传成功后组名和远程文件名的解读!
测试说明:测试文件上传和删除
测试前配置修改
需要修改 /etc/fdfs/client.conf 配置文件的两个参数(自行修改,步骤不再复述;需确保所填的 client 目录存在)
修改小技巧:直接在该文件目录下打开 xftp 传输,直接在传输页面打开文件,修改并保存!
注意:client.conf 文件只在测试的时候才会用到!
base_path = /opt/fastdfs/client
tracker_server = 192.168.154.129:22122
Usage: fdfs_test config_file operation
operation: upload, download, getmeta, setmeta, delete and query_servers
fdfs_trackerd /etc/fdfs/tracker.conf restart
fdfs_storaged /etc/fdfs/storage.conf restart
ps -efgrep fdfs 查看相关进程,是否重启成功
上传成功后会显示一些相关信息,其中最重要的有如下两个信息:【重点!】
group_name:组名(决定文件存到哪个机器)
remote_filename:远程文件名(决定文件存放到哪个磁盘目录下)
FastDFS 存储文件时会自动将文件重命名
该文件存储的路径:/opt/fastdfs/storage/files/data/00/00/wKiagGJUGnWAGvVNAAAAFU1LnYY803.txt
group_name=group1, remote_filename=M00/00/00/wKiagGJUGnWAGvVNAAAAFU1LnYY803.txt
测试文件下载
下载命令格式:
Usage: fdfs_test config_file download group_name remote_filename
在 /home 目录下执行下列命令:
fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/wKiagGJUGnWAGvVNAAAAFU1LnYY803.txt
直接执行:
fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/wKiagGJUGnWAGvVNAAAAFU1LnYY803.txt
没有搭建集群默认只有一个组 group1
FastDFS 存储文件的同时会存储一个与其对应的属性文件(备份文件也是,一个备份文件对应一个属性文件)
后缀名包含 -m 的为属性文件(meta)
在Linux中并没有磁盘一说,是虚拟的
分布式文件系统 FastDFS 的 HTTP 访问
在文件上传的时候,上传成功的信息中有提示我们可以通过某个路径去访问上传的文件,但是我们直接访问这个路径,却不可以,那么已经上传到 FastDFS 文件系统中的文件,我们如何在浏览器中访问呢?FastDFS 提供了一个 Nginx 扩展模块,利用该模块,我们可以通过 Nginx 访问已经上传到 FastDFS 上的文件。
步骤示例:
1.前期准备
将 FastDFS-Nginx 的扩展模块 fastdfs-nginx-module-1.22.zip 上传到 /home/soft 下;
解压:unzip fastdfs-nginx-module-1.22.zip ;
将解压缩的 /home/soft/fastdfs-nginx-module-1.22/src/mod_fastdfs.conf 文件下载到 Windows 中,后边会进行配置使用;
将解压缩的扩展模块源代码的 src 路径 /home/soft/fastdfs-nginx-module-1.22/src拷贝下来,先存着,后面配置重新安装的 Nginx 时会用到这个路径;
2.重装 Nginx
注意:Nginx 的安装需要 Linux 安装相关的几个库,否则编译会出现错误;
如果之前没有安装过 Nginx,则先执行下列命令安装!如果之前安装过 Nginx,下面这相关库的安装步骤就可直接跳过!
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
接下来重新安装 Nginx:因为扩展模块必须在 Nginx 的安装过程中才能添加,所以我们需要重新安装一个 nginx,为了和原来已安装的 Nginx 进行区分,我们把新安装的 Nginx 取名为 nginx_fdfs(指定 nginx 安装路径时进行取名)
进入解压缩后的 Nginx 目录下,按照下面的说明检查路径,并执行下列配置命令:
./configure --prefix=/usr/local/nginx_fdfs --add-module=/home/soft/fastdfs-nginx-module-1.22/src
--prefix 是指定nginx安装路径
--add-module 指定fastDFS的nginx模块(即扩展模块)的源代码路径(之前已让拷贝存着了)
对之前下载下来的扩展模块 src 下的 mod_fastdfs.conf 文件进行如下四项配置:(nginx_mod 目录需要手动创建)
创建目录可使用:mkdir -p /opt/fastdfs/nginx_mod命令
base_path=/opt/fastdfs/nginx_mod
tracker_server=192.168.154.129:22122
url_have_group_name = true
store_path0=/opt/fastdfs/storage/files
在 /usr/local/nginx_fdfs/conf目录下,使用 sz nginx.conf命令,将 nginx.conf 文件下载到 Windows 中,进行如下配置:(注意:是在 server 下新建一个 location 进行配置,千万不要直接在原有的 location 中进行修改!)
下面正则使用固定,可直接复制!
#拦截请求路径中包含 /group[1-9]/M0[0-9] 的请求,用 fastdfs的Nginx 模块进行转发
location ~ /group[1-9]/M0[0-9] {
ngx_fastdfs_module;
在 /usr/local/nginx_fdfs/conf路径下输入 rz -y上传配置好的 nginx.conf 进行原文件覆盖;
检查配置文件是否有语法错误后,启动 Nginx
注意:检查语法错误这步骤可以省略,这里复习一下
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf
如果 master 和 worker 进程都启动成功,则启动成功;
若上面两个缺少一个,则有可能是之前的配置出错!可能是 nginx_mod 目录没有创建,或 nginx.conf 中配置信息有问题!
ps -efgrep nginx
再进行一次文件上传:在 /home/路径下创建一个文件,如 t.text,随便写进去一些内容;
上传到 FastDFS 中,执行:
fdfs_test /etc/fdfs/client.conf upload t.text
复制控制台中返回的示例文件地址,进行访问测试即可(如果访问时直接是下载文件了,而不是显示文件内容;解决这个问题,可参考https://blog.csdn.net/qq_21457601/article/details/51853248?utm_source=blogxgwz3;其实问题不大,目的已经达到了,即使是直接下载了文件,访问测试也是成功的)
http://192.168.154.129/group1/M00/00/00/wKiagGJURUuAMfHuAAAAHUAYZwU38.text
访问流程/扩展模块执行流程图:
FastDFS 在普通 Java 项目中开发示例
在实际项目开发,FastDFS 提供的主要功能
upload:上传文件
download:下载文件
delete:删除文件
FastDFS 文件系统的 Java 客户端
FastDFS 文件系统 Java 客户端是指采用 Java 语言编写的一套程序,专门用来访问 fastDFS 文件系统,其实就是一个 jar 包。
它并没有添加到 maven 的中央仓库中,我们要使用,需要手动下载源代码,编译到自己的本地 maven 仓库。【现在中央仓库好像有了?自己看着选择吧,可以用自己编译的,也可以直接使用中央仓库的】
下载地址:https://github.com/happyfish100/fastdfs(其实之前准备资源,已经让下载过)
将 FastDFS 文件系统 Java 客户端编译到本地 maven 仓库步骤:
进入解压缩的根目录,在文件路径地址栏输入 cmd 命令,进入 dos 窗口,输入 mvn clean install命令,即可将其编译到自己的本地 maven 仓库中,在项目中配置其依赖后可直接使用。
[INFO] Installing C:\Users\linwe\Downloads\fastdfs-client-java-1.28\pom.xml to D:\Java\maven\repository\org\csource\fastdfs-client-java\1.28-SNAPSHOT\fastdfs-client-java-1.28-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
注意:当在项目 pom 中引入该 maven 依赖时,若无法识别出来,则可以在 IDEA 中设置更新下本地仓库。
Java 项目中使用 FastDFS(用的少,一般在web项目中用)
需求:在普通 Java 项目中使用 FastDFS 文件系统实现对文件的上传,下载和删除操作
步骤示例:
在 pom 中添加 FastDFS 客户端依赖,并刷新 pom(可用自己编译的,也可在中央仓库中自己找)
dependencies
!--中央仓库中的FastDFS依赖--
!-- dependency --
!-- groupId com.github.tobato /groupId --
!-- artifactId fastdfs-client /artifactId --
!-- version 1.27.2 /version --
!-- /dependency --
!--自己手动编译的本地仓库中FastDFS依赖--
dependency
groupId org.csource /groupId
artifactId fastdfs-client-java /artifactId
version 1.28-SNAPSHOT /version
/dependency
/dependencies
在 resources 下创建一个 fastdfs.conf 文件,配置 tracker 跟踪器服务,配置自己的 IP
tracker_server=192.168.154.129:22122
此处直接创建并将相关方法封装为工具类,改参数进行测试调用
public class FastDFSUtil {
public static void main(String[] args) {
upload();
// download();
// delete();
* 文件上传
public static void upload() {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
* 文件上传
* 参数1:需上传文件的绝对路径
* 参数2:文件扩展名
* 参数3:文件的属性文件(通常不用上传)
* 返回值:返回一个String数组,此数据非常重要,必须妥善管理,建议存入数据库
* 数组中第一个元素为文件所在组名
* 数组中第二个元素为文件所在远程路径名
String[] result = sc.upload_file("D:/image/love.png", "png", null);
for (String str : result) {
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
* 文件下载
public static void download() {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
* 文件下载
* 参数1:需下载文件的组名
* 参数2:需下载文件的远程文件名
* 参数3:需要保存的本地文件名(绝对路径+文件名)
* 返回值:返回0则下载成功;其他值,则下载失败
String groupName = "group1";
String remoteFileName = "M00/00/00/wKiagWJU6gyEWTbdAAAAAD_4r6Y944.png";
String localFileName = "D:/temp/a.png";
int ret = sc.download_file(groupName, remoteFileName, localFileName);
System.out.println("download======== " + ret);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
* 文件删除
p static void delete() {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
* 文件删除
* 参数1:需删除文件的组名
* 参数2:需删除文件的远程文件名
* 返回值:返回0则删除成功;其他值,则删除失败
String groupName = "group1";
String remoteFileName = "M00/00/00/wKiagWJU6gyEWTbdAAAAAD_4r6Y944.png";
int ret = sc.delete_file(groupName, remoteFileName);
System.out.println("delete======== " + ret);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
在浏览器中输入访问地址进行资源访问测试的时候注意下地址中资源拼接方式:
上传成功返回String数组中两个参数:
group1
M00/00/00/wKiagWJU-t-EJfOFAAAAAD_4r6Y931.png
则访问地址格式为:ip/group1/M00/00/00/wKiagWJU-t-EJfOFAAAAAD_4r6Y931.png
192.168.154.129/group1/M00/00/00/wKiagWJU-t-EJfOFAAAAAD_4r6Y931.png
FastDFS 在 web 项目中开发示例
需求:对项目进行管理,在 WEB 项目中实现对文件的上传下载和删除操作。
流程分析:将文件从本地上传到 tomcat 中,在 tomcat 中拿到文件流,将文件流传到 FastDFS 中,并将上传返回的数据存入数据库中。
步骤:
1.数据库环境搭建
新建查询,执行下列命令,创建 creditor_info 表
示例表中:只有 id、group_name、remote_file_path、old_file_name、file_size、file_type 这几个是重要字段!
-- ----------------------------
-- Table structure for creditor_info
-- ----------------------------
DROP TABLE IF EXISTS `creditor_info`;
CREATE TABLE `creditor_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 主键,
`real_name` varchar(35) DEFAULT NULL COMMENT 债权借款人姓名,
`id_card` varchar(18) DEFAULT NULL COMMENT 债权借款人身份证,
`address` varchar(150) DEFAULT NULL COMMENT 债权借款人地址,
`sex` int(1) DEFAULT NULL COMMENT 1男2女,
`phone` varchar(11) DEFAULT NULL COMMENT 债权借款人电话,
`money` decimal(10,2) DEFAULT NULL COMMENT 债权借款人借款金额,
`group_name` varchar(10) DEFAULT NULL COMMENT 债权合同所在组,
`remote_file_path` varchar(150) DEFAULT NULL COMMENT 债权合同所在路径,
`old_file_name` varchar(255) DEFAULT NULL COMMENT 文件上传前的名字,用于下载文件时指定默认文件名使用,
`file_size` bigint(20) DEFAULT NULL COMMENT 文件大小,用于下载文件啊时提供下载进度,
`file_type` varchar(255) DEFAULT NULL COMMENT 文件类型,用于显示与文件类型相同的图标,作用不是很大,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
-- ----------------------------
-- Records of creditor_info
-- ----------------------------
INSERT INTO `creditor_info` VALUES (1, 张三, 123412341, 北京, 1, 23412341, 12433.00, 1, 1, 1, 1, 1);
INSERT INTO `creditor_info` VALUES (2, 李四, 132414123, 上海, 0, 12344312, 21343.00, null, null, null, null, null);
创建 Spring Boot 项目,选择 Spring Boot DevTools(热部署工具)、Spring Web、Thymeleaf、MySQL、MyBatis 依赖;
注意:如果配置文件中使用的是低版本的 mysql 驱动配置,pom 中的 mysql 需要添加下低版本的版本号对应;
配置 application.properties
# 配置数据库连接信息 注意mysql新旧版本配置不同(如果用的低版本的驱动,pom里需要将mysql也指定下使用低版本的版本号)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.154.129:3306/fastdfs?useUnicode=true characterEncoding=UTF-8 serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
# 开发阶段,关闭thymeleaf的缓存,不然无法看到实时页面
spring.thymeleaf.cache=false
# 去掉html5的语法验证(thymeleaf对html的标签约束非常严格,所有的标签必须有开有闭,比如 br /br 或者 br/ 是可以的,但是 br 会报错,
# 配置spring.thymeleaf.mode=LEGACYHTML5 目的就是为了解决这个问题,可以使页面松校验。)
spring.thymeleaf.mode=LEGACYHTML5
#配置mapper文件路径
mybatis.mapper-locations=classpath:mapper/*.xml
#开启日志
#mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#文件上传大小参考配置
#设置SpringMVC允许上传的单个文件大小,默认为1MB
#spring.servlet.multipart.max-file-size=1MB
#设置SpringMVC表单请求中允许上传文件的总大小,默认为10MB
#spring.servlet.multipart.max-request-size=10MB
3.使用mybatis生成器(逆向工程生成代码)
PS:使用 mybatis 自动代码生成器,可自动生成 model 实体类, dao 接口以及 mapper 映射文件。
此处使用 mapper 文件和 dao 接口分开管理的方式。
在 pom 的 plugins 标签下添加 mybatis 自动代码生成插件
!--mybatis自动代码生成插件--
plugin
groupId org.mybatis.generator /groupId
artifactId mybatis-generator-maven-plugin /artifactId
version 1.3.6 /version
configuration
!--配置文件的位置:在项目的根目录下,和src平级--
configurationFile GeneratorMapper.xml /configurationFile
verbose true /verbose
overwrite true /overwrite
/configuration
/plugin
在项目根目录下创建 GeneratorMapper.xml文件,其与 src 平级;将下列内容拷贝到文件中;依照注释修改配置,修改完后,点开右侧 maven 快捷窗口,使用当前项目下 plugins 下 mybatis-genetate 下的 mybatis 自动代码生成插件进行生成。
?xml version="1.0" encoding="UTF-8"?
!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"
generatorConfiguration
!-- 指定连接数据库的JDBC驱动包所在位置,指定到你本机的完整路径 --
classPathEntry location="D:\Java\tools\mysql-connector-java-8.0.28.jar"/
!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 --
context id="tables" targetRuntime="MyBatis3"
!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 --
commentGenerator
property name="suppressAllComments" value="true" /
/commentGenerator
!-- 配置数据库连接信息 --
jdbcConnection driver connectionURL="jdbc:mysql://192.168.154.129:3306/fastdfs?useUnicode=true amp;characterEncoding=UTF-8 amp;serverTimezone=GMT%2B8"
userId="root"
password="123"
!--MySQL 不支持 schema 或者 catalog 所以需要添加这个--
!--设置原因参考:https://blog.csdn.net/qq_40233736/article/details/83314596--
property name="nullCatalogMeansCurrent" value="true" /
/jdbcConnection
!-- 生成model类,targetPackage指定model类的包名, targetProject指定生成的model放在eclipse的哪个工程下面--
javaModelGenerator targetPackage="com.luis.model"
targetProject="D:\1a-Projects\test-projects\fastdfs\springboot-web-fastdfs\src\main\java"
property name="enableSubPackages" value="false" /
property name="trimStrings" value="false" /
/javaModelGenerator
!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在eclipse的哪个工程下面 --
sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"
property name="enableSubPackages" value="false" /
/sqlMapGenerator
!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名, targetProject指定生成的Mapper接口放在eclipse的哪个工程下面 --
javaClientGenerator type="XMLMAPPER" targetPackage="com.luis.dao" targetProject="src/main/java"
property name="enableSubPackages" value="false" /
/javaClientGenerator
!-- 数据库表名及对应的Java模型类名 --
table tableName="creditor_info" domainObjectName="CreditorInfo"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/
table tableName="b_bid_info" domainObjectName="BidInfo"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/
table tableName="b_income_record" domainObjectName="IncomeRecord"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/
table tableName="b_recharge_record" domainObjectName="RechargeRecord"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/
table tableName="u_finance_account" domainObjectName="FinanceAccount"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/
/context
/generatorConfiguration
在主启动类上添加包扫描注解@MapperScan,扫描 dao 所在的包(防止后面忘记了,先加上)
作用:扫描 dao 下的所有 mapper 类作为 Mapper 映射文件。
@SpringBootApplication
@MapperScan(basePackages = "com.luis.dao")
public class SpringbootWebFastdfsApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebFastdfsApplication.class, args);
public String creditors(Model model) {
List CreditorInfo creditorInfoList = creditorInfoServer.queryAll();
model.addAttribute("creditorInfoList", creditorInfoList);
return "creditors";
public List CreditorInfo queryAll() {
List CreditorInfo list = creditorInfoMapper.selectAll();
return list;
tr th:each="creditorInfo:${creditorInfoList}"
td th:text="${creditorInfo.id}" 序号 /td
td th:text="${creditorInfo.realName}" 姓名 /td
td th:text="${creditorInfo.sex == 1?男:女}" 性别 /td
td th:text="${creditorInfo.phone}" 电话 /th
td th:text="${creditorInfo.address}" 地址 /td
span th:if="${creditorInfo.remoteFilePath == null creditorInfo.remoteFilePath == }"
a th:href="@{/upload/${creditorInfo.id}}" 上传 /a
/span
span th:if="${creditorInfo.remoteFilePath != null creditorInfo.remoteFilePath != }"
a th:href="@{/download}" 下载 /a
a th:href="@{/delete}" 删除 /a
/span
/td
/tr
/table
/body
/html
5.Web 中操作 FastDFS 完成上传
6.Web 中操作 FastDFS 完成下载
7.Web 中操作 FastDFS 完成删除
由于操作不好记录,以下相关实现提供相关实现参考:
相关页面参考:
creditors.html
!DOCTYPE html
html lang="en" xmlns:th="http://www.thymeleaf.org"
head
meta charset="UTF-8"
title creditors.html /title
/head
body
table
th 序号 /th
th 姓名 /th
th 性别 /th
th 电话 /th
th 地址 /th
th /th
/tr
tr th:each="creditorInfo:${creditorInfoList}"
td th:text="${creditorInfo.id}" 序号 /td
td th:text="${creditorInfo.realName}" 姓名 /td
td th:text="${creditorInfo.sex == 1?男:女}" 性别 /td
td th:text="${creditorInfo.phone}" 电话 /th
td th:text="${creditorInfo.address}" 地址 /td
span th:if="${creditorInfo.remoteFilePath == null creditorInfo.remoteFilePath == }"
a th:href="@{/upload/${creditorInfo.id}}" 上传 /a
/span
span th:if="${creditorInfo.remoteFilePath != null creditorInfo.remoteFilePath != }"
a th:href="@{/download/${creditorInfo.id}}" 下载 /a
a th:href="@{/delete/${creditorInfo.id}}" 删除 /a
/span
/td
/tr
/table
/body
/html
upload.html
!DOCTYPE html
html lang="en" xmlns:th="http://www.thymeleaf.org"
head
meta charset="UTF-8"
title upload.html /title
/head
body
!-- 上传文件的表单,method必须为post,并且必须指定enctype属性为multipart/form-data --
!-- enctype="multipart/form-data" 简单说明:让表单以二进制的形式传递数据,支持流文件类型 --
form th:action="@{/upload}" target="curPage" method="post" enctype="multipart/form-data"
姓名: span th:text="${creditorInfo.realName}" /span br/
性别: span th:text="${creditorInfo.sex==1?男:女}" /span br/
电话: span th:text="${creditorInfo.phone}" /span br/
地址: span th:text="${creditorInfo.address}" /span br/
文件: input type="file" name="myFile" / br/
input type="hidden" name="id" th:value="${creditorInfo.id}" / br/
input type="submit" value="上传文件" br/
/form
!-- 嵌入式框架框架 --
iframe name="curPage" /iframe
/body
/html
success.html
!DOCTYPE html
html lang="en"
head
meta charset="UTF-8"
title Title /title
script type="text/javascript"
if (confirm("[[${msg}]]")) {
window.top.location.href = "[[${url}]]";
/script
/head
body
/body
/html
工具类参考:
public class FastDFSUtil {
private FastDFSUtil() {
* 文件上传
* @param fileBuff 上传文件的字节数组
* @param fileExtName 上传文件的扩展名
* @return String数组
* 数组中第一个元素为文件所在组名
* 数组中第二个元素为文件所在远程路径名
public static String[] upload(byte[] fileBuff, String fileExtName) {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
* 文件上传
* 参数1:需上传文件的字节数组
* 参数2:文件扩展名
* 参数3:文件的属性文件(通常不用上传)
* 返回值:返回一个String数组,此数据非常重要,必须妥善管理,建议存入数据库
* 数组中第一个元素为文件所在组名
* 数组中第二个元素为文件所在远程路径名
return sc.upload_file(fileBuff, fileExtName, null);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
return null;
* 文件下载
* @param groupName 需下载文件的组名
* @param remoteFileName 需下载文件的远程文件名
* @return byte[] 需下载文件的字节数组
public static byte[] download(String groupName, String remoteFileName) {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
return sc.download_file(groupName, remoteFileName);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
return null;
* 文件删除
* @param groupName 需删除文件的组名
* @param remoteFileName 需删除文件的远程文件名
public static void delete(String groupName, String remoteFileName) {
try {
//读取FastDFS配置文件,用于将所有的tracker的地址读取到内存中
ClientGlobal.init("fastdfs.conf");
// 使用无参构造方式创建tracker客户端对象(配合配置文件使用),用于获取tracker和storage的服务端对象
TrackerClient tc = new TrackerClient();
// 通过tracker客户端对象获取tracker和storage的服务端对象
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
// 通过tracker和storage的服务端对象创建Storage客户端对象,来操作数据
StorageClient sc = new StorageClient(ts, ss);
sc.delete_file(groupName, remoteFileName);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
控制器类参考:
@Controller
public class CreditorInfoController {
@Resource
private CreditorInfoServer creditorInfoServer;
@RequestMapping("/")
public String creditors(Model model) {
List CreditorInfo creditorInfoList = creditorInfoServer.queryAll();
model.addAttribute("creditorInfoList", creditorInfoList);
return "creditors";
@GetMapping("/upload/{id}")
public String toUpload(@PathVariable Integer id, Model model) {
CreditorInfo creditorInfo = creditorInfoServer.findById(id);
model.addAttribute("creditorInfo", creditorInfo);
return "upload";
* 文件上传
* 参数MultipartFile:为Spring提供的一个类,专门用于封装请求中的文件数。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。