java应用整合fastdfs实现文件 上传及下载

对于fastdfs的安装部署请参阅另一篇博文:fastdfs安装篇 本篇主要讲在springboot项目中如何整合fastdfs实现文件上传 下载 及删除, 项目demo gitee 地址:https://gitee.com/JackSong2019/fastdfs_demo.git 整合方式有两种,一种是fastdfs官方提供的 fastdfs-client-java, 另一种是其它开发者基于原作者YuQing与yuqin发布的java客户端的基础上进行了大量的重构的开源项目 fastDFS_Client

一、基于官方提供的fastdfs-client-java方式集成

github地址:https://github.com/happyfish100/fastdfs-client-java

1、引入依赖

注意版本:引入的fastdfs-client-java需在和安装的fastdf server端版本对应,否则上传过程中会出现异常 我使用的fastdfs server 为6.06,引入的依赖为1.30

org.csource

fastdfs-client-java

1.30-SNAPSHOT

注意:如果通过maven仓库下载失败,解决办法 第一种:使用maven从源码安装

mvn clean install

第二种:使用maven从jar文件安装 注意替换正确的版本号 version

mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java -Dversion=${version} -Dpackaging=jar -Dfile=fastdfs-client-java-${version}.jar

2、配置文件 可以用 .conf配置文件,也可用properties配置文件

2.1 .conf配置文件 、所在目录、加载优先顺序

配置文件名fdfs_client.conf(或使用其它文件名xxx_yyy.conf)

文件所在位置可以是项目classpath(或OS文件系统目录比如/opt/): /opt/fdfs_client.conf C:\Users\James\config\fdfs_client.conf

优先按OS文件系统路径读取,没有找到才查找项目classpath,尤其针对linux环境下的相对路径比如: fdfs_client.conf config/fdfs_client.conf

配置文件内容

注1:tracker_server指向您自己IP地址和端口,1-n个

注2:除了tracker_server,其它配置项都是可选的

connect_timeout = 2

network_timeout = 30

charset = UTF-8

http.tracker_http_port = 80

http.anti_steal_token = no

http.secret_key = FastDFS1234567890

tracker_server = 10.0.11.247:22122

tracker_server = 10.0.11.248:22122

tracker_server = 10.0.11.249:22122

connection_pool.enabled = true

connection_pool.max_count_per_entry = 500

connection_pool.max_idle_time = 3600

connection_pool.max_wait_time_in_ms = 1000

2.2 .properties 配置文件、所在目录、加载优先顺序

配置文件名 fastdfs-client.properties(或使用其它文件名 xxx-yyy.properties)

文件所在位置可以是项目classpath(或OS文件系统目录比如/opt/): /opt/fastdfs-client.properties C:\Users\James\config\fastdfs-client.properties

优先按OS文件系统路径读取,没有找到才查找项目classpath,尤其针对linux环境下的相对路径比如: fastdfs-client.properties config/fastdfs-client.properties

注1:properties 配置文件中属性名跟 conf 配置文件不尽相同,并且统一加前缀"fastdfs.",便于整合到用户项目配置文件

注2:fastdfs.tracker_servers 配置项不能重复属性名,多个 tracker_server 用逗号","隔开

注3:除了fastdfs.tracker_servers,其它配置项都是可选的

fastdfs.connect_timeout_in_seconds = 5

fastdfs.network_timeout_in_seconds = 30

fastdfs.charset = UTF-8

fastdfs.http_anti_steal_token = false

fastdfs.http_secret_key = FastDFS1234567890

fastdfs.http_tracker_http_port = 80

fastdfs.tracker_servers = 10.0.11.201:22122,10.0.11.202:22122,10.0.11.203:22122

fastdfs.connection_pool.enabled = true

fastdfs.connection_pool.max_count_per_entry = 500

fastdfs.connection_pool.max_idle_time = 3600

fastdfs.connection_pool.max_wait_time_in_ms = 1000

3、加载配置

3.1 .conf配置文件加载

// 加载原 conf 格式文件配置 不同路径存储获取方式 选择合适的即可

ClientGlobal.init("fdfs_client.conf");

ClientGlobal.init("config/fdfs_client.conf");

ClientGlobal.init("/opt/fdfs_client.conf");

ClientGlobal.init("C:\\Users\\James\\config\\fdfs_client.conf");

3.2 .properties 配置文件加载

// 加载 properties 格式文件配置:

ClientGlobal.initByProperties("fastdfs-client.properties");

ClientGlobal.initByProperties("config/fastdfs-client.properties");

ClientGlobal.initByProperties("/opt/fastdfs-client.properties");

ClientGlobal.initByProperties("C:\\Users\\James\\config\\fastdfs-client.properties");

// 加载 Properties 对象配置:

Properties props = new Properties();

props.put(ClientGlobal.PROP_KEY_TRACKER_SERVERS, "10.0.11.101:22122,10.0.11.102:22122");

ClientGlobal.initByProperties(props);

3.3 字符串方式

// 加载 trackerServers 字符串配置:

String trackerServers = "10.0.11.101:22122,10.0.11.102:22122";

ClientGlobal.initByTrackers(trackerServers);

3.4 加载结果 查看

# 打印配置

System.out.println("ClientGlobal.configInfo(): " + ClientGlobal.configInfo());

# 控制台显示的打印结果

ClientGlobal.configInfo(): {

g_connect_timeout(ms) = 5000

g_network_timeout(ms) = 30000

g_charset = UTF-8

g_anti_steal_token = false

g_secret_key = FastDFS1234567890

g_tracker_http_port = 80

g_connection_pool_enabled = true

g_connection_pool_max_count_per_entry = 500

g_connection_pool_max_idle_time(ms) = 3600000

g_connection_pool_max_wait_time_in_ms(ms) = 1000

trackerServers = 10.0.11.101:22122,10.0.11.102:22122

}

4、编写上传 下载 删除相关方法

package com.ydsz.util;

import org.csource.common.NameValuePair;

import org.csource.fastdfs.ClientGlobal;

import org.csource.fastdfs.StorageClient;

import org.csource.fastdfs.TrackerClient;

import org.csource.fastdfs.TrackerServer;

import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

public class FastdfsJavaClientUtil {

/**

* 获取tracker客户端

* @return

* @throws Exception

*/

public static StorageClient initStorageClient() throws Exception {

// 1、加载配置文件

ClientGlobal.init("E:\\study\\fastdfs_demo\\src\\main\\resources\\fdfs_client.conf");

// 2 创建一个trackerClient

TrackerClient tracker = new TrackerClient();

// 3 使用TrackerClient对象获取trackerServer对象

TrackerServer trackerServer = tracker.getTrackerServer();

// 4、创建一个StorageClient对象

return new StorageClient(trackerServer);

}

/**

* 关闭tracker

* @param storageClient

*/

public static void closeClient(StorageClient storageClient) {

if(storageClient == null) return;

try {

storageClient.close();

}catch (Exception e){

e.printStackTrace();

}catch (Throwable e){

e.printStackTrace();

}

}

/**

* @param file 上传的文件

* @throws Exception

*/

public static String[] upload(MultipartFile file) throws Exception{

InputStream inputStream = file.getInputStream();

int length = inputStream.available();

byte[] bytes = new byte[length];

inputStream.read(bytes);

NameValuePair[] metaList = new NameValuePair[1];

metaList[0] = new NameValuePair("fileName", file.getOriginalFilename());

StorageClient storageClient = initStorageClient();

String[] result = storageClient.upload_file(bytes, null, metaList);

closeClient(storageClient);

return result;

}

/**

* 下载文件

* @param groupName storage名

* @param fileKey 文件key

* @param localFileName 下载到本地的文件名

* @throws Exception

*/

public static void download(String groupName,String fileKey,String localFileName) throws Exception {

StorageClient storageClient = initStorageClient();

storageClient.download_file(groupName, fileKey,localFileName);

closeClient(storageClient);

}

/**

* 下载文件

* @param groupName storage名

* @param fileKey 文件key

* @throws Exception

*/

public static byte[] download(String groupName,String fileKey) throws Exception {

StorageClient storageClient = initStorageClient();

byte[] bytes = storageClient.download_file(groupName, fileKey);

closeClient(storageClient);

return bytes;

}

/**

* 删除文件

* @param groupName storage名

* @param fileKey 文件key

* @throws Exception

*/

public static void delFile(String groupName,String fileKey) throws Exception {

StorageClient storageClient = initStorageClient();

storageClient.delete_file(groupName, fileKey);

closeClient(storageClient);

}

}

二、基于fastDFS_Client集成

github地址:https://github.com/tobato/FastDFS_Client fastDFS_Client 是在原作者YuQing与yuqih发布的java客户端基础上进行了大量重构工作,便于Java工作者学习与阅读。 当前客户端单元测试全部通过,服务端版本是FastDFS_V5.07

主要特性

对关键部分代码加入了单元测试,便于理解与服务端的接口交易,提高接口质量 将以前对byte硬解析风格重构为使用 对象+注解 的形式,尽量增强了代码的可读性 支持对服务端的连接池管理(commons-pool2) 支持上传图片时候检查图片格式,并且自动生成缩略图 在SpringBoot当中自动导入依赖

1.在项目Pom当中加入依赖

Maven依赖为

com.github.tobato

fastdfs-client

1.27.2

在Maven当中配置依赖以后,SpringBoot项目将会自动导入FastDFS依赖 但注意 如果 是 1.26.4 以前的版本需要下面的方式引入

// 将FastDFS-Client客户端引入本地化项目的方式非常简单,

// 在SpringBoot项目/src/[com.xxx.主目录]/conf当中配置

/**

* 导入FastDFS-Client组件

* @author tobato

*

*/

@Configuration

@Import(FdfsClientConfig.class)

// 解决jmx重复注册bean的问题

@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)

public class ComponetImport {

// 导入依赖组件

}

// 只需要一行注解 @Import(FdfsClientConfig.class)就可以拥有带有连接池的FastDFS Java客户端了

2、application.yml当中配置fdfs相关参数

# ===================================================================

# 分布式文件系统FDFS配置

# ===================================================================

fdfs:

so-timeout: 1501

connect-timeout: 601

thumb-image: #缩略图生成参数

width: 150

height: 150

tracker-list: #TrackerList参数,支持多个

- 192.168.1.105:22122

- 192.168.1.106:22122

pool:

#从池中借出的对象的最大数目(配置为-1表示不限制)

max-total: -1

#获取连接时的最大等待毫秒数(默认配置为5秒)

max-wait-millis: 5000

#每个key最大连接数

max-total-per-key: 50

#每个key对应的连接池最大空闲连接数

max-idle-per-key: 10

#每个key对应的连接池最小空闲连接数

min-idle-per-key: 5

其中pool部分为连接池的管理参数 应用启动后拥有两个连接池管理对象: Tracker连接池(TrackerConnectionManager) Storage连接池(FdfsConnectionManager) 必要的时候可以注入这两个对象,跟踪打印并分析连接池的情况

3、使用接口服务对Fdfs服务端进行操作

3.1 接口说明

主要接口包括 TrackerClient - TrackerServer接口 GenerateStorageClient - 一般文件存储接口 (StorageServer接口) FastFileStorageClient - 为方便项目开发集成的简单接口(StorageServer接口) AppendFileStorageClient - 支持文件续传操作的接口 (StorageServer接口)

3.4 代码示例

package com.ydsz.controller;

import com.github.tobato.fastdfs.domain.fdfs.StorePath;

import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;

import com.github.tobato.fastdfs.domain.upload.FastFile;

import com.github.tobato.fastdfs.service.FastFileStorageClient;

import com.ydsz.util.FastdfsJavaClientUtil;

import org.apache.commons.lang3.StringUtils;

import org.csource.fastdfs.StorageServer;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import javax.servlet.http.HttpServletResponse;

@RestController

@RequestMapping("/fastdfs")

public class FileClientController {

@Resource

FastFileStorageClient fastFileStorageClient;

// 自己服务器ip+端口

private String baseUrl ="http://127.0.0.1:80/";

/**

* 文件上传

* @param file

* @return

* @throws Exception

*/

@PostMapping("/upload")

public String upload(MultipartFile file) throws Exception {

StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(),

file.getSize(),

StringUtils.substringAfterLast(file.getOriginalFilename(), "."),

null);

return baseUrl + storePath.getFullPath();

}

/**

* @param groupName

* @param fileKey

* @param response

* @throws Exception

*/

@PostMapping("/download")

public void download(String groupName, String fileKey, HttpServletResponse response) throws Exception {

byte[] download = fastFileStorageClient.downloadFile(groupName, fileKey, new DownloadByteArray());

// 将download以流的方式返回

response.getOutputStream().write(download);

}

/**

* 删除文件

* @param filePath 文件的完整路径

*/

@PostMapping("/delete")

public void delFile(String filePath) {

fastFileStorageClient.deleteFile(filePath);

}

}

4、上传文件大小配置 当上传较大文件时 可能会存在异常情况 增加以下配置即可解决

package com.ydsz.config;

import org.springframework.boot.web.servlet.MultipartConfigFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.util.unit.DataSize;

import javax.servlet.MultipartConfigElement;

@Configuration

public class FileConfig {

@Bean

public MultipartConfigElement multipartConfigElement() {

MultipartConfigFactory factory = new MultipartConfigFactory();

//单个文件最大 50MB

factory.setMaxFileSize(DataSize.ofBytes(50 * 1024 *1024));

/// 设置总上传数据总大小 200MB

factory.setMaxRequestSize(DataSize.ofBytes(200 * 1024 *1024));

return factory.createMultipartConfig();

}

}

项目demo gitee 地址:https://gitee.com/JackSong2019/fastdfs_demo.git

参考文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。