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
<dependency>
<groupid>org.csource</groupid>
<artifactid>fastdfs-client-java</artifactid>
<version>1.30-snapshot</version>
</dependency>
注意:如果通过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依赖为
<dependency>
<groupid>com.github.tobato</groupid>
<artifactid>fastdfs-client</artifactid>
<version>1.27.2</version>
</dependency>
在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();
}
}
发表评论