写在前面

在《【FastDFS】小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?》和《【FastDFS】面试官:如何实现文件的大规模分布式存储?(全程实战)》文章中,我们详细的搭建了FastDFS环境。那么,现在环境是有了,如何将FastDFS整合到项目中呢?今天,我们就一起来聊聊这个问题。

注:工程源码已提交到:https://github.com/sunshinelyz/mykit-fastdfs

编译Java客户端

在FastDFS的官方Github上,专门有一个FastDFS Java客户端的项目,链接地址为:https://github.com/happyfish100/fastdfs-client-java

我们将Java客户端代码下载的本地,然后进入项目的目录,使用Maven进行编译,如下所示。

git clone https://github.com/happyfish100/fastdfs-client-java.git
cd fastdfs-client-java
mvn clean install -Dmaven.test.skip=true

接下来,我们需要将FastDFS的Java客户端编译安装到本地的Maven仓库。

mvn install:install-file -DgroupId=com.fastdfs -DartifactId=fastdfs-client-java -Dversion=1.29 -Dpackaging=jar -Dfile=fastdfs-client-java-1.29-SNAPSHOT.jar

到此,我们就在本地编译安装了FastDFS的Java客户端。

搭建项目

编辑pom.xml文件

我们在IDEA中创建一个Maven项目,并在pom.xml文件中引入SpringBoot相关依赖和我们自己编译的FastDFS的Java客户端。最终,pom.xml文件的依赖如下所示。

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<skip_maven_deploy>false</skip_maven_deploy>
<java.version>1.8</java.version>
<logback.version>1.1.7</logback.version>
<slf4j.version>1.7.21</slf4j.version>
<common.logging>1.2</common.logging>
<fastjson.version>1.2.51</fastjson.version>
<fastdfs.client.version>1.29</fastdfs.client.version>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${common.logging}</version>
</dependency> <!-- log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency> <dependency>
<groupId>com.fastdfs</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>${fastdfs.client.version}</version>
</dependency>
</dependencies>

创建配置文件

(1)在项目的src/main/resources目录下创建SpringBoot的配置文件application.yml,文件内容如下所示。

server:
port: 9999
servlet:
context-path: /resource
tomcat:
uri-encoding: UTF-8 spring:
servlet:
multipart:
max-file-size: 1024MB
max-request-size: 1024MB
main:
allow-bean-definition-overriding: true
profiles:
include: test
active: test
output:
ansi:
enabled: detect

文件指定了项目启动后监听的端口,访问的根路径、项目编码、文件上传的大小,并指定了运行时的环境。

(2)在项目的src/main/resources目录下创建logback-spring.xml日志文件,具体配置见源码工程。

(3)在项目的src/main/resources目录下创建fastdfs_client.conf文件,主要用来配置与FastDFS的连接信息。

connect_timeout = 200
network_timeout = 3000
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
tracker_server = 192.168.175.100:22122

至此,项目搭建完成。接下来,我们就一起实现项目的功能。

项目开发

创建工具类

首先,我们在项目的io.mykit.fastdfs.utils包下创建FastDFSClientUtils工具类。这里,我给出工具类的核心实现,其他部分小伙伴们参加源码工程。

/**
* @author binghe
* @description FastDFS分布式文件系统操作客户端
*/
public class FastDFSClientUtils { private static Logger logger = LoggerFactory.getLogger(FastDFSClientUtils.class); private static TrackerClient trackerClient; public static void setFile(String filePath) {
try {
logger.info("初始化分布式文件系统服务开始...");
if(filePath == null || filePath.trim().isEmpty()) {
filePath = "fastdfs_client.conf";
}
ClientGlobal.init(filePath);
TrackerGroup trackerGroup = ClientGlobal.g_tracker_group;
trackerClient = new TrackerClient(trackerGroup);
logger.info("初始化分布式文件系统服务完成...");
} catch (Exception e) {
logger.error("加载文件异常:{}",e );
}
} /**
* @param data 数据
* @param extName 文件扩展名
* @return 上传成功返回id,失败返回null
*/
public static String upload(byte[] data, String extName) {
TrackerServer trackerServer = null;
StorageServer storageServer = null;
StorageClient1 storageClient1 = null;
try {
NameValuePair[] meta_list = null; // new NameValuePair[0]; trackerServer = trackerClient.getTrackerServer();
if (trackerServer == null) {
logger.error("getConnection return null");
}
storageServer = trackerClient.getStoreStorage(trackerServer);
storageClient1 = new StorageClient1(trackerServer, storageServer);
String fileid = storageClient1.upload_file1(data, extName, meta_list);
return fileid;
} catch (Exception ex) {
logger.error("上传文件异常:{}", ex);
return null;
}finally{
try {
storageClient1.close();
} catch (IOException e) {
e.printStackTrace();
}
storageClient1 = null;
}
}

创建返回实体类

我们在io.mykit.fastdfs.bean包下创建ResourceBean类,用于SpringBoot接口返回结果数据,如下所示。

/**
* @author binghe
* @version 1.0.0
* @description 上传图片后的返回数据
*/
public class ResourceBean implements Serializable {
private static final long serialVersionUID = -2788538880352897307L; /**
* 文件的访问路径
*/
private String fileUrl; /**
* 文件名称
*/
private String fileName; public ResourceBean() {
super();
} public ResourceBean(String fileUrl, String fileName) {
super();
this.fileUrl = fileUrl;
this.fileName = fileName;
} public String getFileUrl() {
return fileUrl;
} public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
} }

其中,定义了文件的访问路径fileUrl和文件的名称fileName。也就是说,文件上传成功后,我们会向客户端返回文件的访问路径和文件的名称信息。

创建常量类

在io.mykit.fastdfs.constants包下创建ResourcesConstants常量类,ResourcesConstants类中主要定义了访问文件的基础路径和获取文件完整访问路径的方法,如下所示。

/**
* @author binghe
* @version 1.0.0
* @description 常量
*/
public class ResourcesConstants {
private static final String BASE_RESOURCES_URL = "http://192.168.175.100/";
public static String getResourcesUrl(String fileId) {
return BASE_RESOURCES_URL.concat(fileId);
}
}

创建Controller类

在项目的io.mykit.fastdfs.controller包下创建ResourceController类,用于定义文件上传的接口。这个类的功能也比较简单,就是定义一个文件上传接口,接收文件,并调用FastDFSClientUtils工具类的upload(byte[], String)方法,将文件上传到FastDFS中,如下所示。

/**
* @author binghe
* @version 1.0.0
* @description 上传文件接口
*/
@RestController
@RequestMapping(value = "/resources/")
public class ResourceController { @RequestMapping(value={"/upload"}, method=RequestMethod.POST)
@ResponseBody
public ResourceBean upload(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response){
String extName = "";
String fileName = "";
String originalFilename = file.getOriginalFilename();
if(originalFilename.contains(".")) {
//拆分文件路径
String[] fileArray = originalFilename.split("\\.");
//获取文件扩展名
extName = fileArray[1];
//获取文件名
fileName = fileArray[0];
}else {
fileName = originalFilename;
}
byte[] bytes = null;
try {
bytes = file.getBytes(); //将文件转换成字节流形式
} catch (IOException e) {
e.printStackTrace();
}
//调用上传文件的具体方法
String fileId= FastDFSClientUtils.upload(bytes,extName);
return new ResourceBean(ResourcesConstants.getResourcesUrl(fileId), fileName);
}
}

创建启动类

在项目的io.mykit.fastdfs包下,创建项目启动类ResourceStarter,如下所示。

/**
* @author binghe
* @version 1.0.0
* @description 启动
*/
@SpringBootApplication
public class ResourceStarter {
public static void main(String[] args) {
try {
String filePath = "fastdfs_client.conf";
if(args.length > 0) {
filePath = args[0];
}
FastDFSClientUtils.setFile(filePath);
SpringApplication.run(ResourceStarter.class, args);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

从代码可以看出,ResourceStarter启动类的main方法中,为filePath变量定义了一个默认的文件路径为fastdfs_client.conf,当启动项目时,为main()方法传递了参数,则会使用第一个参数覆盖掉filePath默认的值,并调用FastDFSClientUtils类的setFile()方法将filePath传递到FastDFSClientUtils类中进行初始化操作。

创建html文件

最后,我们需要创建一个index.html文件,用于测试文件上传操作。index.html文件的内容也比较简单,如下所示。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文件上传和下载</title>
</head>
<body>
<form action='http://192.168.175.100:9999/resource/resources/upload' method='post' enctype='multipart/form-data'>
<input type='file' name='file'>
<button type='submit'>上传</button>
</form>
</body>
</html>

至此,我们整个项目就开发完成了。

项目测试

首先,我们在IDEA中将mykit-fastdfs项目打包成mykit-fastdfs.jar文件,然后将mykit-fastdfs.jar文件上传到服务器的/usr/local/java目录下,同时,我们将项目的src/main/resources目录下的fastdfs_client.conf文件,复制一份到服务器的/usr/local/java目录下。

在服务器命令行输入如下命令启动mykit-fastdfs.jar。

nohup java -jar /usr/local/java/mykit-fastdfs.jar /usr/local/java/fastdfs_client.conf >> /dev/null &

接下来,我们将index.html文件放到Nginx安装目录下的html/test目录下。此时,在浏览器地址栏中输入http://192.168.175.100/test/index.html就能够打开页面。

我们通过index.html页面将文件上传到FastDFS文件系统之后,浏览器中会显示返回的结果数据,一个是文件的访问路径fileUrl,一个是文件的名称fileName,如下所示。

{
"fileUrl": "http://192.168.175.100/group1/M00/00/00/Ch8FQl9wfkSASTnYAACSPnJ7giA366.jpg",
"fileName": "QQ截图20200609234534"
}

具体如下图所示。

我们打开fileUrl标识的文件访问路径,http://192.168.175.100/group1/M00/00/00/Ch8FQl9wfkSASTnYAACSPnJ7giA366.jpg,如下所示。



可以看到,浏览器能够正确显示上传的图片,说明我们已经在项目中成功整合了FastDFS的Java客户端。

重磅福利

微信搜一搜【冰河技术】微信公众号,关注这个有深度的程序员,每天阅读超硬核技术干货,公众号内回复【PDF】有我准备的一线大厂面试资料和我原创的超硬核PDF技术文档,以及我为大家精心准备的多套简历模板(不断更新中),希望大家都能找到心仪的工作,学习是一条时而郁郁寡欢,时而开怀大笑的路,加油。如果你通过努力成功进入到了心仪的公司,一定不要懈怠放松,职场成长和新技术学习一样,不进则退。如果有幸我们江湖再见!

另外,我开源的各个PDF,后续我都会持续更新和维护,感谢大家长期以来对冰河的支持!!

写在最后

如果你觉得冰河写的还不错,请微信搜索并关注「 冰河技术 」微信公众号,跟冰河学习高并发、分布式、微服务、大数据、互联网和云原生技术,「 冰河技术 」微信公众号更新了大量技术专题,每一篇技术文章干货满满!不少读者已经通过阅读「 冰河技术 」微信公众号文章,吊打面试官,成功跳槽到大厂;也有不少读者实现了技术上的飞跃,成为公司的技术骨干!如果你也想像他们一样提升自己的能力,实现技术能力的飞跃,进大厂,升职加薪,那就关注「 冰河技术 」微信公众号吧,每天更新超硬核技术干货,让你对如何提升技术能力不再迷茫!

【FastDFS】SpringBoot整合FastDFS实战,我只看这一篇!!的更多相关文章

  1. windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看

    windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看 1. 新建excel表格 A B C D E 姓 名 全名 登录名 密码 李 四 李四 李四 test123!@ ...

  2. springboot整合fastdfs实现上传和下载

    FastDFS_Client源码 https://github.com/tobato/FastDFS_Client 友情提示:由于FastDFS_Client这个源码不是很多,并且目前没有找到相关文档 ...

  3. SpringBoot整合Fastdfs,实现图片上传(IDEA)

    我们部署Fastdfs,就是为了实现文件的上传. 现在使用idea整合Fastdfs,实现图片上传 部署环境:Centos7部署分布式文件存储(Fastdfs) 利用Java客户端调用FastDFS ...

  4. 第2-1-4章 SpringBoot整合FastDFS文件存储服务

    目录 5 SpringBoot整合 5.1 操作步骤 5.2 项目依赖 5.3 客户端开发 5.3.1 FastDFS配置 5.3.2 FastDFS配置类 5.3.3 文件工具类 5.3.4 文件上 ...

  5. Https双向验证与Springboot整合测试-人来人往我只认你

    1 简介 不知不觉Https相关的文章已经写了6篇了,本文将是这个专题的最后一篇,起码近期是最后一篇.前面6篇讲的全都是单向的Https验证,本文将重点介绍一下双向验证.有兴趣的同学可以了解一下之前的 ...

  6. springboot整合elasticJob实战(纯代码开发三种任务类型用法)以及分片系统,事件追踪详解

    一 springboot整合 介绍就不多说了,只有这个框架是当当网开源的,支持分布式调度,分布式系统中非常合适(两个服务同时跑不会重复,并且可灵活配置分开分批处理数据,贼方便)! 这里主要还是用到zo ...

  7. SpringBoot 整合 MongoDB 实战介绍

    一.介绍 在前面的文章中,我们详细的介绍了 MongoDB 的配置和使用,如果你对 MongoDB 还不是很了解,也没关系,在 MongoDB 中有三个比较重要的名词:数据库.集合.文档! 数据库(D ...

  8. SpringBoot整合FastDFS实现图片的上传

     文件的上传和预览在web开发领域是随处可见,存储的方式有很多,本文采用阿里巴巴余庆大神开发的FastDFS进行文件的存储,FastDFS是一个分布式文件存储系统,可以看我上一篇博文,有安装和配置教程 ...

  9. springboot整合fastdfs

    首先pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

随机推荐

  1. 《Java从入门到失业》第三章:基础语法及基本程序结构(四):基本数据类型(字符编码和char型)

    3.6.4字符编码 咦?怎么好像有东西乱入了?不是讲基本数据类型么?哈哈,因为还剩下最后一个char型了,因为char型会牵涉到Unicode编码相关,因此我决定先科普一下字符集编码. 我儿子现在上小 ...

  2. 洛谷 P3951 NOIP 2017 小凯的疑惑

    洛谷 P3951 NOIP 2017 小凯的疑惑 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付 ...

  3. WPF Devexpress控件库中ChartControl--实现不等距x轴

    一.概要 解决问题--ChartControl不等距x轴显示 二.CS代码 用过ChartControl的开发者们应该都知道,ChartControl中设置x轴间距间隔都是固定的数值. 比如(间隔10 ...

  4. 原生 JavaScript30 练习 Day 1 (原生JS控制键盘模拟击鼓)

     代码如下   <!DOCTYPE html> <html lang="en"> <head>     <meta charset=&qu ...

  5. element-ul二次封装table表格

    在项目中el的表格使用的地方太多了,若不进行封装,使用的时候页面会显得非常的冗余且难以维护,有时表格样式还不能做到一致:今天分享一个在工作中封装的表格 由于大多代码都在页面有介绍,就不在外面解释了 一 ...

  6. 洛谷 P4995 跳跳!

    思路 贪心 从大到小排序,然后反复横跳,记录两个指针 \(l=1, r=n\),从 \(1\) 跳到 \(n\),再从 \(n\) 跳到 \(2\),然后从 \(2\) 跳到 \(n - 1\)--, ...

  7. Java开发环境搭建的准备工作

    Java开发环境搭建的准备工作 网络配置(修改hosts) 什么时候需要 比如我们在安装homeBrew的时候会遇到 curl: (7) Failed to connect to raw.github ...

  8. JVM中的对象

    虚拟机中的对象 对象的分配 虚拟机遇到一条new指令时:根据new的参数是否能在常量池中定位到一个类的符号引用,如果没有,说明还未定义该类,抛出ClassNotFoundException: 1)检查 ...

  9. js拖拽原理及简单实现(渣渣自学)

    第一步 首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式 ...

  10. MongoDB基础总结

    1.数据可基本操作 1. 创建数据库 use  databaseName 选择一个数据库,如果数据库不存在就自动创建一个数据库 只有向数据库中插入数据时,数据库才会被真实创建出来,而当数据库中没有数据 ...