前言:

      这里用的不是余庆先生用的fastdfs客户端,而是github中一个大佬写的,功能也很强大,可以生成缩略图,并且经常更新,支持springboot2.0版本。

     附地址:This is a java client lib for FastDFS.

实现本案例的话,必须先搭建fastdfs环境,并且启动。可以参考我的另一篇博客,对fastdfs进行一个环境搭建。


项目结构:

springboot fastjson Long 丢失精度 springboot整合fastdfs_spring

 

这里我用的是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);

    }