前言:
这里用的不是余庆先生用的fastdfs客户端,而是github中一个大佬写的,功能也很强大,可以生成缩略图,并且经常更新,支持springboot2.0版本。
附地址:This is a java client lib for FastDFS.
实现本案例的话,必须先搭建fastdfs环境,并且启动。可以参考我的另一篇博客,对fastdfs进行一个环境搭建。
项目结构:
这里我用的是springboot2.1.0版本,fastdfs客户端是1.26.1版本。
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.1-RELEASE</version>
</dependency>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
ComponetImport :这个是fastdfs客户端人家写好的,直接拷贝过来用即可。
package com.lucifer.fastdfs.conf;
import com.github.tobato.fastdfs.FdfsClientConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;
/**
* @author: Lucifer
* @create: 2018-11-10 23:15
* @description:导入FastDFS-Client组件
**/
@Configuration
@Import(FdfsClientConfig.class)
/**
* 解决jmx重复注册bean的问题
*/
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {
// 导入依赖组件
}
variables :是我用来存放常量的一个类,根据自己的需要,进行相应修改。
package com.lucifer.fastdfs;
import java.net.InetSocketAddress;
/**
* @author: Lucifer
* @create: 2018-11-11 04:00
* @description: 定义常用的变量
**/
public class variables {
//安装fastdfs的虚拟机的ip
public static final String ip_home = "192.168.59.131";
//默认文件本地文件路径
public static final String pathname = "C:\\Users\\13871\\Desktop\\01.jpg";
//组名,跟你在fastdfs配置文件中的一致
public static final String groupName = "group1";
//fastDFS存储文件的path,这个path路径需要你执行测试方法中上传后,获取的path粘贴过来,用于查
询、删除的
public static final String path = "M00/00/00/wKg7g1vnC0uAF33PAADWMguR3lU360.png";
//默认文件名称,你所需要上传的图片名称
public static final String filename = "01.jpg";
//默认文件格式,后缀名,设置上传后在fastdfs存储的格式,你可以改成其它格式图片,fastdfs只支持几种常用格式的,自己百度可以查查,jpg和png都是可以的
public static final String fileExtName = "jpg";
//带组名的path
public static final String filePath = groupName + path;
public final static int port = 22122;
public final static int store_port = 23000;
public static InetSocketAddress address = new InetSocketAddress(ip_home, port);
public static InetSocketAddress store_address = new InetSocketAddress(ip_home, store_port);
//超时时间
public static final int soTimeout = 550;
//连接时间
public static final int connectTimeout = 500;
}
application.yml,配置fastdfs的信息
# ===================================================================
# 分布式文件系统FDFS配置
# ===================================================================
fdfs:
so-timeout: 1501 #上传的超时时间
connect-timeout: 601 #连接超时时间
thumb-image: #缩略图生成参数
width: 150
height: 150
tracker-list: #TrackerList参数,支持多个
- 192.168.59.131:22122
测试类:(ps:执行完下载的测试方法后,项目中会多出一个文件图片)
metaDataSet:文件元信息,当然也可以直接写null.
package com.lucifer.fastdfs.test;
import com.github.tobato.fastdfs.domain.FileInfo;
import com.github.tobato.fastdfs.domain.MateData;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.domain.ThumbImageConfig;
import com.github.tobato.fastdfs.proto.storage.DownloadFileWriter;
import com.github.tobato.fastdfs.proto.storage.StorageDownloadCommand;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.lucifer.fastdfs.variables;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@RunWith(SpringRunner.class)
@SpringBootTest
public class FastdfsApplicationTests {
private static final Logger LOGGER = LoggerFactory.getLogger(FastdfsApplicationTests.class);
File file = null;
Set<MateData> metaDataSet = null;
@Before
public void newFile() {
metaDataSet = createMetaData();
file = new File(variables.pathname);
}
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private ThumbImageConfig thumbImageConfig;
/**
* 测试1--图片上传
*/
@Test
public void testUpload() throws FileNotFoundException {
//上传图片
StorePath storePath = this.storageClient.uploadFile(new FileInputStream(file), file.length(), variables.fileExtName, metaDataSet);
printlnPath(storePath);
}
/**
* 测试2--图片上传缩略图
*/
@Test
public void testCrtThumbImage() throws FileNotFoundException {
//上传图片的缩略图
StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage(new FileInputStream(file), file.length(), variables.fileExtName, metaDataSet);
String fullPath = thumbImageConfig.getThumbImagePath(storePath.getFullPath());
System.out.println("【图片缩略图带有组名的路径】:" + fullPath);
printlnPath(storePath);
}
/**
* 查询
*/
@Test
public void testQuery() {
FileInfo fileInfo = this.storageClient.queryFileInfo(variables.groupName, variables.path);
System.out.println("图片信息如下:\n" + fileInfo.getCrc32() + "\n" + new Date(fileInfo.getCreateTime()) + "\n" + fileInfo.getFileSize() + "\n" + fileInfo.getSourceIpAddr());
}
/**
* 删除
*/
@Test
public void testDel() {
this.storageClient.deleteFile(variables.filePath);
}
/**
* 删除(效果同上删除)
*/
@Test
public void testDel2() {
this.storageClient.deleteFile(variables.groupName, variables.path);
}
/**
* 下载文件
*/
@Test
public void downLoadFile() {
DownloadFileWriter callback = new DownloadFileWriter(variables.filename);
this.storageClient.downloadFile(variables.groupName, variables.path, callback);
// StorageDownloadCommand<String> stringStorageDownloadCommand = new StorageDownloadCommand<>(variables.groupName, variables.path, callback);
// String fileName = commandTestBase.executeStoreCmd(stringStorageDownloadCommand);
}
/**
* 创建元信息
*
* @return
*/
private Set<MateData> createMetaData() {
Set<MateData> metaDataSet = new HashSet<MateData>();
metaDataSet.add(new MateData("Author", "lucifer"));
metaDataSet.add(new MateData("CreateDate", "2018-11-11"));
return metaDataSet;
}
private void printlnPath(StorePath storePath) {
//组名
System.out.println("【组名】:" + storePath.getGroup());
//带组名的文件地址
System.out.println("【带组名的文件地址】:" + storePath.getFullPath());
//不带组名的文件地址
System.out.println("【不带组名的文件地址】:" + storePath.getPath());
}
}
上述的测试方法中的下载是一种方法,再展示一种下载的方法:
这里创建CommandTestBase 的类,然后加上注解@Component,将其纳入spring容器当中,然后在测试类中引入CommandTestBase 这个类,调用里面的executeStoreCmd()方法,同样可以下载文件。
package com.lucifer.fastdfs.test;
/**
* @author: Lucifer
* @create: 2018-11-11 05:38
* @description:
**/
import com.lucifer.fastdfs.variables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.tobato.fastdfs.conn.ConnectionManager;
import com.github.tobato.fastdfs.conn.FdfsConnectionPool;
import com.github.tobato.fastdfs.conn.PooledConnectionFactory;
import com.github.tobato.fastdfs.proto.FdfsCommand;
import org.springframework.stereotype.Component;
/**
* command测试基类
*
* @author lucifer
*
*/
@Component
public class CommandTestBase {
/** 日志 */
protected static Logger LOGGER = LoggerFactory.getLogger(CommandTestBase.class);
/**
* 连接池
*/
protected ConnectionManager manager = createConnectionManager();
/**
* 执行Tracker交易命令
*
* @param command
* @return
*/
protected <T> T executeTrackerCmd(FdfsCommand<T> command) {
return manager.executeFdfsCmd(variables.address, command);
}
/**
* 执行存储交易命令
*
* @param command
* @return
*/
protected <T> T executeStoreCmd(FdfsCommand<T> command) {
return manager.executeFdfsCmd(variables.store_address, command);
}
private ConnectionManager createConnectionManager() {
return new ConnectionManager(createPool());
}
private FdfsConnectionPool createPool() {
PooledConnectionFactory factory = new PooledConnectionFactory();
factory.setConnectTimeout(variables.connectTimeout);
factory.setSoTimeout(variables.soTimeout);
return new FdfsConnectionPool(new PooledConnectionFactory());
}
}
测试类中,可以将测试方法做如下修改,即可实现另一方法的下载。
#引入CommandTestBase 这个类
@Autowired
private CommandTestBase commandTestBase;
/**
* 下载文件
*/
@Test
public void downLoadFile() {
DownloadFileWriter callback = new DownloadFileWriter(variables.filename);
StorageDownloadCommand<String> stringStorageDownloadCommand = new StorageDownloadCommand<>(variables.groupName, variables.path, callback);
String fileName = commandTestBase.executeStoreCmd(stringStorageDownloadCommand);
LOGGER.info("----文件下载成功-----{}", fileName);
}