【FastFDS】SpringBoot整合FastDFS实战(附完整工程源码)

简介: 在《【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"
}

具体如下图所示。

微信图片_20211119160249.jpg

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

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

相关文章
|
5天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
29天前
|
JavaScript Java 关系型数据库
美妆商城系统 SpringBoot + Vue 【毕业设计 资料 + 源码】
这篇文章介绍了一个使用SpringBoot + Vue + Mybatis + Mysql技术栈开发的美妆商城系统,包括系统功能划分、部分页面截图和前后端源码示例,并提供了GitHub上的源码链接。
美妆商城系统 SpringBoot + Vue 【毕业设计 资料 + 源码】
|
1月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
21天前
|
Java API UED
【实战秘籍】Spring Boot开发者的福音:掌握网络防抖动,告别无效请求,提升用户体验!
【8月更文挑战第29天】网络防抖动技术能有效处理频繁触发的事件或请求,避免资源浪费,提升系统响应速度与用户体验。本文介绍如何在Spring Boot中实现防抖动,并提供代码示例。通过使用ScheduledExecutorService,可轻松实现延迟执行功能,确保仅在用户停止输入后才触发操作,大幅减少服务器负载。此外,还可利用`@Async`注解简化异步处理逻辑。防抖动是优化应用性能的关键策略,有助于打造高效稳定的软件系统。
30 2
|
28天前
|
安全 Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+jsp实现的健身房管理系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术实现的健身房管理系统。随着健康生活观念的普及,健身房成为日常锻炼的重要场所,高效管理会员信息、课程安排等变得尤为重要。该系统旨在通过简洁的操作界面帮助管理者轻松处理日常运营挑战。技术栈包括:JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Shiro、Spring Boot 2.0等。系统功能覆盖登录、会员管理(如会员列表、充值管理)、教练管理、课程管理、器材管理、物品遗失管理、商品管理及信息统计等多方面。
|
26天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
|
29天前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。
|
1月前
|
JavaScript Java Maven
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和Vue.js实现的在线求职平台。该平台采用了前后端分离的架构,使用Spring Boot作为后端服务
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
|
1月前
|
NoSQL JavaScript 前端开发
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
文章介绍了如何使用SpringBoot和Vue实现一个校园二手系统,采用前后端分离技术。系统具备完整的功能,包括客户端和管理员端的界面设计、个人信息管理、商品浏览和交易、订单处理、公告发布等。技术栈包括Vue框架、ElementUI、SpringBoot、Mybatis-plus和Redis。文章还提供了部分源代码,展示了前后端的请求接口和Redis验证码功能实现,以及系统重构和模块化设计的一些思考。
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
|
1月前
|
NoSQL 关系型数据库 MySQL
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
78 2