编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

FastDFS实战总结,分布式文件存储,高并发高可用,看这篇就够了

wxchong 2024-08-09 11:37:27 开源技术 9 ℃ 0 评论

1、环境准备

1.1、使用的系统软件

1.2、编译环境

yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y

1.3、磁盘目录

mkdir /home/dfs #创建数据存储目录
cd /usr/local/src #切换到安装目录准备下载安装包

1.4、安装libfatscommon

git clone https://github.com/happyfish100/libfastcommon.git --depth 1 
#如果下载慢可使用gitee地址:
git clone https://gitee.com/fastdfs100/libfastcommon.git --depth 1
cd libfastcommon/./make.sh && ./make.sh install  #编译安装

1.5、安装FastDFS

cd ../ #返回上一级目录

git clone https://github.com/happyfish100/fastdfs.git --depth 1
# 如果下载慢可使用gitee地址:
git clone https://gitee.com/fastdfs100/fastdfs.git --depth 1

cd fastdfs/
./make.sh && ./make.sh install #编译安装
#配置文件准备
cp /etc/fdfs/tracker.conf.sample  /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample  /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample  /etc/fdfs/client.conf #客户端文件,测试用
cp /usr/local/src/fastdfs/conf/http.conf  /etc/fdfs/ #供nginx访问使用
cp /usr/local/src/fastdfs/conf/mime.types  /etc/fdfs/ #供nginx访问使用

1.6、安装fastdfs-nginx-module

cd ../ #返回上一级目录
git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
# 如果下载慢可使用gitee地址:
git clone https://gitee.com/fastdfs100/fastdfs-nginx-module.git --depth 1

cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf   /etc/fdfs

1.7、安装nginx

wget http://nginx.org/download/nginx-1.15.4.tar.gz 
#下载nginx压缩包tar -zxvf nginx-1.15.4.tar.gz 
#解压
cd nginx-1.15.4/
#添加fastdfs-nginx-module模块
  ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ make && make install 
  #编译安装

2、单机部署

2.1、tracker配置

#服务器ip为: 
192.168.52.1
#我建议用ftp下载下来这些文件 本地修改
vim /etc/fdfs/tracker.conf

#需要修改的内容如下
port=22122  # tracker服务器端口(默认22122,一般不修改)
base_path=/home/dfs   # 存储日志和数据的根目录

2.2、storage配置

vim /etc/fdfs/storage.conf

#需要修改的内容如下
port=23000  # storage服务端口(默认23000,一般不修改)
base_path=/home/dfs  # 数据和日志文件存储根目录
store_path0=/home/dfs  # 第一个存储目录
tracker_server=192.168.52.1:22122  # tracker服务器IP和端口
http.server_port=8888  # http访问文件的端口(默认8888,看情况修改,和nginx中保持一致)

2.3、client测试

vim /etc/fdfs/client.conf
#需要修改的内容如下
base_path=/home/dfs
tracker_server=192.168.52.1:22122    #tracker服务器IP和端口

#保存后测试,返回ID表示成功 如:group1/M00/00/00/xx.tar.gz
fdfs_upload_file /etc/fdfs/client.conf  /usr/local/src/nginx-1.15.4.tar.gz

2.4、配置nginx访问

vim /etc/fdfs/mod_fastdfs.conf
#需要修改的内容如下
tracker_server=192.168.52.1:22122  #tracker服务器IP和端口
url_have_group_name=true
store_path0=/home/dfs
#配置nginx.config
vim /usr/local/nginx/conf/nginx.conf
#添加如下配置
server {    
    listen       8888;    ## 该端口为storage.conf中的http.server_port相同    
    server_name  localhost;   
    location ~/group[0-9]/ {        
        ngx_fastdfs_module;   
    }    
    error_page   500 502 503 504  /50x.html;    
    location = /50x.html {    
        root   html;    
    }
}
#测试下载,用外部浏览器访问刚才已传过的nginx安装包,引用返回的ID
http://192.168.52.1:8888/group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz
#弹出下载单机部署全部跑通

3、分布式部署

3.1、tracker配置

#服务器ip为:
192.168.52.2,192.168.52.3,192.168.52.4
#我建议用ftp下载下来这些文件 本地修改
vim /etc/fdfs/tracker.conf
#需要修改的内容如下
port=22122  # tracker服务器端口(默认22122,一般不修改)
base_path=/home/dfs  # 存储日志和数据的根目录

3.2、storage配置

vim /etc/fdfs/storage.conf
#需要修改的内容如下
port=23000  # storage服务端口(默认23000,一般不修改)
base_path=/home/dfs  # 数据和日志文件存储根目录
store_path0=/home/dfs  # 第一个存储目录
tracker_server=192.168.52.2:22122  # 服务器1
tracker_server=192.168.52.3:22122  # 服务器2
tracker_server=192.168.52.4:22122  # 服务器3
http.server_port=8888  # http访问文件的端口(默认8888,看情况修改,和nginx中保持一致)

3.3、client测试

vim /etc/fdfs/client.conf
#需要修改的内容如下
base_path=/home/moe/dfs
tracker_server=192.168.52.2:22122  # 服务器1
tracker_server=192.168.52.3:22122  # 服务器2
tracker_server=192.168.52.4:22122  # 服务器3
#保存后测试,返回ID表示成功 如:group1/M00/00/00/xx.tar.gz
fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/nginx-1.15.4.tar.gz

3.4、配置nginx访问

vim /etc/fdfs/mod_fastdfs.conf
#需要修改的内容如下
tracker_server=192.168.52.2:22122  # 服务器1
tracker_server=192.168.52.3:22122  # 服务器2
tracker_server=192.168.52.4:22122  # 服务器3
url_have_group_name=true
store_path0=/home/dfs
#配置nginx.config
vim /usr/local/nginx/conf/nginx.conf
#添加如下配置
server {    
    listen       8888;    ## 该端口为storage.conf中的http.server_port相同   
    server_name  localhost;    
    location ~/group[0-9]/ {        
      ngx_fastdfs_module;    
    }    
    error_page   500 502 503 504  /50x.html;    
    location = /50x.html {   
    	root   html;    
    }
}

4、启动

4.1、防火墙

#不关闭防火墙的话无法使用
systemctl stop firewalld.service #关闭
systemctl restart firewalld.service #重启

4.2、tracker

/etc/init.d/fdfs_trackerd start #启动tracker服务
/etc/init.d/fdfs_trackerd restart #重启动tracker服务
/etc/init.d/fdfs_trackerd stop #停止tracker服务
chkconfig fdfs_trackerd on #自启动tracker服务

4.3、storage

/etc/init.d/fdfs_storaged start #启动storage服务
/etc/init.d/fdfs_storaged restart #重动storage服务
/etc/init.d/fdfs_storaged stop #停止动storage服务
chkconfig fdfs_storaged on #自启动storage服务

4.4、nginx

/usr/local/nginx/sbin/nginx #启动nginx
/usr/local/nginx/sbin/nginx -s reload #重启nginx
/usr/local/nginx/sbin/nginx -s stop #停止nginx

4.5、检测集群

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
# 会显示会有几台服务器 有3台就会 显示 Storage 1-Storage 3的详细信息

5、说明

5.1、配置文件

tracker_server #有几台服务器写几个
group_name #地址的名称的命名
bind_addr #服务器ip绑定
store_path_count #store_path(数字)有几个写几个
store_path(数字) #设置几个储存地址写几个 从0开始

5.2、可能遇到的问题

如果不是root 用户 你必须在除了cd的命令之外 全部加sudo
如果不是root 用户 编译和安装分开进行 先编译再安装
如果上传成功 但是nginx报错404 先检查mod_fastdfs.conf文件中的store_path0是否一致
如果nginx无法访问 先检查防火墙 和 mod_fastdfs.conf文件tracker_server是否一致
如果不是在/usr/local/src文件夹下安装 可能会编译出错
如果 unknown directive "ngx_fastdfs_module" in /usr/local/nginx/conf/nginx.conf:151,可能是nginx一直是启动的,必须要重启nginx才可以,`nginx -s reload`无效。

6、 FastDFS java client SDK 使用

6.1、构建jar包

第一种方式: 使用maven从源码安装

gitee源码地址:https://gitee.com/fastdfs100/fastdfs-client-java.git

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

使用git clone 克隆源码到本地仓库,然后执行 mvn clean install 即可。

这里需要注意直接install的话只能打包源码生成jar,但是没有源码,如果遇到问题调试不方便,所以在源码的pom.xml中添加源码打包插件,这样在执行install后jar包和源码包都会生成。如下:

<!--配置生成源码包-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.0.1</version>
    <configuration>
        <attach>true</attach>
    </configuration>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

第二种方式: 使用maven从jar文件安装到maven仓库

打开命令行,输入如下命令:

mvn install:install-file -Dfile=jar包的位置 -DgroupId=上面的groupId -DartifactId=上面的artifactId -Dversion=上面的version -Dpackaging=jar 

真实案例如下:

mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java -Dversion=1.29-SNAPSHOT -Dpackaging=jar -Dfile=F:\mav3\repository\org\csource\fastdfs-client-java\fastdfs-client-java-1.29-SNAPSHOT.jar

完成以上步骤后,添加maven依赖jar包:

<!--fastdfs分布式文件存储依赖-->
<dependency>
	<groupId>org.csource</groupId>
	<artifactId>fastdfs-client-java</artifactId>
	<version>1.29-SNAPSHOT</version>
</dependency>

6.2、单机环境需对外开放端口

环境配置好以后需要在linux服务器开放如下端口,否则客户端无法访问,报连接超时。

第一:nginx的服务端口:8888

第二:tracker server的端口:22122

第三:storage server的端口:23000

6.3、安全访问处理

增加token和时间戳防止盗链,步骤如下:

第一步:将token设置为true,并且生成一个密钥,这个密钥至关重要放在服务端,泄露后会产生安全问题,具体生成方法建议生成一个UUID然后用md5加密后用作密钥。

fastdfs.http_anti_steal_token=true
fastdfs.http_secret_key=64edb5dd9fd277cb0686d56f1c634266

第二步:修改linux服务器安装的配置文件http.conf,一般存放地址为:/etc/fdfs/http.conf 。注意,这里的secretkey的值要和上面生成的密钥值保持一致。tokencheck_fail可以注释,也可以保留,保留建议配置一个可以访问的正确路径。

# if use token to anti-steal
# default value is false (0)
http.anti_steal.check_token = true

# token TTL (time to live), seconds
# default value is 600
http.anti_steal.token_ttl = 900

# secret key to generate anti-steal token
# this parameter must be set when http.anti_steal.check_token set to true
# the length of the secret key should not exceed 128 bytes
http.anti_steal.secret_key = 64edb5dd9fd277cb0686d56f1c634266

# return the content of the file when check token fail
# default value is empty (no file sepecified)
http.anti_steal.token_check_fail = /home/dfs/123456.png

第三步:重启服务

/etc/init.d/fdfs_trackerd restart #重启动tracker服务

/etc/init.d/fdfs_storaged restart #重动storage服务

/usr/local/nginx/sbin/nginx -s reload #重启nginx

第四步:创建生成安全访问地址的方法。这里的secret要和上面的密钥保持一致。这里特别强调一点ProtoCommon.getToken方法的第一个参数不包含”组“group,第二个参数是时间戳,第三个参数是密钥。

/**
  * @auther: mk
  * @param: 参数说明
  * @return: 返回值说明
  * @date: 2020/4/21 21:35
  * @desc: (fastdfs开启token和时间戳验证,防盗链)
*/
@GetMapping(value = "/sys/common/dfsfile/token")
public Result<Object> getFastDFSToken(@RequestParam(value = "dfsFilePath", required = true) String dfsFilePath) {
    String secret = "64edb5dd9fd277cb0686d56f1c634266";
    //unix时间戳 以秒为单位
    int ts = (int) (System.currentTimeMillis() / 1000);
    String token = null;
    try {
        String remoteFileName = dfsFilePath.substring(dfsFilePath.indexOf("/") + 1);
        token = ProtoCommon.getToken(remoteFileName, ts, secret);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (MyException e) {
        e.printStackTrace();
    }

    Result<Object> result = new Result<>();
    if (StrUtil.isBlank(token)) {
        result.error500("获取失败!");
    } else {
        StringBuilder sb = new StringBuilder();
        sb.append(nginxHost);
        sb.append(dfsFilePath);
        sb.append("?token=").append(token);
        sb.append("&ts=").append(ts);

        result.setCode(200);
        result.setMessage("获取成功!");
        result.setResult(sb.toString());
    }
    return result;
}

生成访问地址示例如下:

http://192.168.42.104:8888/group1/M00/00/00/wKgqaF6e_BaACnxTAAHOIjxzNLk072.png?token=31c0b171f6a589fcf539635bd140f4ba&ts=1587477535

第五步:如果经过以上四步发现生成的token验证无法通过,请检查确认服务器时间基本是一致的,注意服务器时间不能相差太多,不要相差到分钟级别。

至此FastDFS防盗链配置已完成!!!

6.4、JAVA客户端接入示例

6.4.1、创建配置文件

在src/main/resource目录下创建 fastdfs-client.properties 文件,内容如下:

fastdfs.connect_timeout_in_seconds=5
fastdfs.network_timeout_in_seconds=30
fastdfs.charset=UTF-8
fastdfs.http_anti_steal_token=true
fastdfs.http_secret_key=64edb5dd9fd277cb0686d56f1c634266
fastdfs.http_tracker_http_port=8888
fastdfs.tracker_servers=192.168.42.104: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

在springboot的配置文件中添加如下内容:

#fastdfs分布式文件存储访问路径
fastdfs.nginx.host=http://192.168.42.104:8888/

6.4.2、创建FastDFS公共调用类

完成fastdfs的上传、下载、删除、查看文件信息功能

/**
 * @auther: mk
 * @date: 2020/4/21 18:25
 * @desc: (fastdfs上传文件信息)
 */
public class FastDFSFileUtil {
    //文件名称
    private String name;

    //文件内容
    private byte[] content;

    //文件扩展名
    private String ext;

    //文件加密名称
    private String md5;

    //元信息:作者名称
    private String author;

    public FastDFSFileUtil(String name, byte[] content, String ext, String author) {
        this.name = name;
        this.content = content;
        this.ext = ext;
        this.author = author;
    }

    public FastDFSFileUtil(String name, byte[] content, String ext) {
        super();
        this.name = name;
        this.content = content;
        this.ext = ext;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    public String getExt() {
        return ext;
    }

    public void setExt(String ext) {
        this.ext = ext;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}
import cn.hutool.core.io.resource.ClassPathResource;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @auther: mk
 * @date: 2020/4/21 16:34
 * @desc: (fastdfs分布式文件存储工具类)
 */
public class FastDFSUtil {

    private static final Logger logger = LoggerFactory.getLogger(FastDFSUtil.class);

    private FastDFSUtil() {
    }

    ;

    static {
        try {
            ClassPathResource resource = new ClassPathResource("fastdfs-client.properties");
            Properties properties = new Properties();
            properties.load(resource.getStream());
            ClientGlobal.initByProperties(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        System.out.println("ClientGlobal.configInfo(): " + ClientGlobal.configInfo());
    }


    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 18:08
     * @desc: (fastdfs上传服务器)
     */
    public static String[] upload(FastDFSFileUtil fastDFSFile) {
        logger.info("File Name: " + fastDFSFile.getName() + "File Length:" + fastDFSFile.getContent().length);

        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", fastDFSFile.getAuthor());

        String[] uploadResults = null;
        StorageClient storageClient = null;
        try {
            long startTime = System.currentTimeMillis();
            storageClient = getStorageClient();
            uploadResults = storageClient.upload_file(fastDFSFile.getContent(), fastDFSFile.getExt(), meta_list);
            logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");

            if (uploadResults == null && storageClient != null) {
                logger.error("upload file fail, error code:" + storageClient.getErrorCode());
            }
            String groupName = uploadResults[0];
            String remoteFileName = uploadResults[1];

            logger.info("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);
        } catch (IOException e) {
            logger.error("IO Exception when uploadind the file:" + fastDFSFile.getName(), e);
        } catch (MyException e) {
            logger.error("Non IO Exception when uploadind the file:" + fastDFSFile.getName(), e);
        } finally {
            if (storageClient != null) {
                try {
                    storageClient.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }
        return uploadResults;
    }

    public static FileInfo getFile(String groupName, String remoteFileName) {
        StorageClient storageClient = null;
        try {
            storageClient = getStorageClient();
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (IOException e) {
            logger.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (MyException e) {
            logger.error("Non IO Exception: Get File from Fast DFS failed", e);
        } finally {
            if (storageClient != null) {
                try {
                    storageClient.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 18:09
     * @desc: (fastdfs下载文件)
     */
    public static InputStream download(String groupName, String remoteFileName) {
        StorageClient storageClient = null;
        try {
            storageClient = getStorageClient();
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            InputStream ins = new ByteArrayInputStream(fileByte);
            return ins;
        } catch (IOException e) {
            logger.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            logger.error("Non IO Exception: Get File from Fast DFS failed", e);
        } finally {
            if (storageClient != null) {
                try {
                    storageClient.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 18:09
     * @desc: (fastdfs删除文件)
     */
    public static boolean deleteFile(String groupName, String remoteFileName) {
        StorageClient storageClient = getStorageClient();
        int i = 100;
        try {
            i = storageClient.delete_file(groupName, remoteFileName);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        } finally {
            if (storageClient != null) {
                try {
                    storageClient.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }
        if (i == 0) { //@return 0 for success, none zero for fail (error code)
            logger.info("delete file successfully!!!" + i);
            return true;
        } else {
            return false;
        }

    }

    public static StorageServer[] getStoreStorages(String groupName) {
        TrackerServer trackerServer = null;
        StorageServer[] storageServers = null;
        try {
            TrackerClient trackerClient = new TrackerClient();
            trackerServer = trackerClient.getTrackerServer();
            storageServers = trackerClient.getStoreStorages(trackerServer, groupName);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return storageServers;
    }

    public static ServerInfo[] getFetchStorages(String groupName, String filename) {
        TrackerServer trackerServer = null;
        ServerInfo[] serverInfos = null;
        try {
            TrackerClient trackerClient = new TrackerClient();
            trackerServer = trackerClient.getTrackerServer();
            serverInfos = trackerClient.getFetchStorages(trackerServer, groupName, filename);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return serverInfos;

    }

    public static String getTrackerUrl() {
        return "http://" + getTrackerServer().getInetSocketAddress().getHostString() + ":" + ClientGlobal.getG_tracker_http_port() + "/";
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 17:27
     * @desc: (存储客户端)
     */
    private static StorageClient getStorageClient() {
        TrackerServer trackerServer = getTrackerServer();
        StorageClient storageClient = new StorageClient(trackerServer, null);
        return storageClient;
    }

    private static TrackerServer getTrackerServer() {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = null;
        try {
            trackerServer = trackerClient.getTrackerServer();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return trackerServer;
    }

}

6.4.3、创建业务调用处理公共方法

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import org.csource.common.MyException;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.ProtoCommon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @auther: mk
 * @param: 参数说明
 * @return: 返回值说明
 * @date: 2020/4/21 22:29
 * @desc: (公共访问控制器)
 */
@RestController
public class CommonController {

    private final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Value("${fastdfs.nginx.host}")
    String nginxHost;

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 19:46
     * @desc: (上传文件)
     */
    @PostMapping(value = "/sys/common/upload")
    public Result<Object> upload(HttpServletRequest request) {
        Result<Object> result = new Result<>();
        try {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile mf = multipartRequest.getFile("dfsFile");// 获取上传文件对象
            if (null != mf) {
                String originalFilename = mf.getOriginalFilename();// 获取文件名
                String[] uploadResult = FastDFSUtil.upload(new FastDFSFileUtil(originalFilename, mf.getBytes(), originalFilename.substring(originalFilename.lastIndexOf(".") + 1)));
                if (null != uploadResult && uploadResult.length > 0) {
                    String dbpath = uploadResult[0] + File.separator + uploadResult[1];
                    if (dbpath.contains("\\")) {
                        dbpath = dbpath.replace("\\", "/");
                    }
                    Map<String, String> returnMap = new HashMap<>();
                    returnMap.put("name", originalFilename);
                    returnMap.put("path", dbpath);
                    result.setResult(returnMap);
                    result.setMessage("上传成功!");
                    result.setSuccess(true);
                } else {
                    result.error500("上传失败!");
                }
            }
        } catch (IOException e) {
            result.error500(e.getMessage());
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 19:46
     * @desc: (下载文件)
     */
    @GetMapping(value = "/sys/common/download")
    public void download(@RequestParam(value = "dfsFilePath", required = true) String dfsFilePath,
                         @RequestParam(value = "fileName", required = false) String fileName,
                         HttpServletResponse response) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            String groupName = dfsFilePath.substring(0, dfsFilePath.indexOf("/"));
            String remoteFileName = dfsFilePath.substring(dfsFilePath.indexOf("/") + 1);
            String ext = dfsFilePath.substring(dfsFilePath.lastIndexOf("."));
            InputStream is = FastDFSUtil.download(groupName, remoteFileName);
            response.setContentType("application/force-download");// 设置强制下载不打开            
            response.addHeader("Content-Disposition", "attachment;fileName=" +
                    new String((StrUtil.isBlank(fileName) ? IdUtil.simpleUUID() : fileName).getBytes("UTF-8"), "iso-8859-1") + ext);
            inputStream = new BufferedInputStream(is);
            outputStream = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, len);
            }
            response.flushBuffer();
        } catch (Exception e) {
            log.error("文件下载失败" + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 20:06
     * @desc: (删除文件)
     */
    @GetMapping(value = "/sys/common/delete")
    public Result<?> delete(@RequestParam(value = "dfsFilePath", required = true) String dfsFilePath) {
        String groupName = dfsFilePath.substring(0, dfsFilePath.indexOf("/"));
        String remoteFileName = dfsFilePath.substring(dfsFilePath.indexOf("/") + 1);
        boolean deleteResult = FastDFSUtil.deleteFile(groupName, remoteFileName);
        Result<?> result = new Result<>();
        if (deleteResult) {
            result.setCode(200);
            result.setMessage("删除成功!");
        } else {
            result.error500("删除失败!");
        }
        return result;
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 20:34
     * @desc: (获取上传文件详细信息)
     */
    @GetMapping(value = "/sys/common/dfsfile/detail")
    public Result<Object> detail(@RequestParam(value = "dfsFilePath", required = true) String dfsFilePath) {
        String groupName = dfsFilePath.substring(0, dfsFilePath.indexOf("/"));
        String remoteFileName = dfsFilePath.substring(dfsFilePath.indexOf("/") + 1);
        FileInfo fileInfo = FastDFSUtil.getFile(groupName, remoteFileName);
        Result<Object> result = new Result<>();
        if (null != fileInfo) {
            result.setCode(200);
            result.setResult(fileInfo);
            result.setMessage("获取成功!");
        } else {
            result.error500("获取失败!");
        }
        return result;
    }

    /**
     * @auther: mk
     * @param: 参数说明
     * @return: 返回值说明
     * @date: 2020/4/21 21:35
     * @desc: (fastdfs开启token和时间戳验证,防盗链)
     */
    @GetMapping(value = "/sys/common/dfsfile/token")
    public Result<Object> getFastDFSToken(@RequestParam(value = "dfsFilePath", required = true) String dfsFilePath) {
        String secret = "64edb5dd9fd277cb0686d56f1c634266";
        //unix时间戳 以秒为单位
        int ts = (int) (System.currentTimeMillis() / 1000);
        String token = null;
        try {
            String remoteFileName = dfsFilePath.substring(dfsFilePath.indexOf("/") + 1);
            token = ProtoCommon.getToken(remoteFileName, ts, secret);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }

        Result<Object> result = new Result<>();
        if (StrUtil.isBlank(token)) {
            result.error500("获取失败!");
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append(nginxHost);
            sb.append(dfsFilePath);
            sb.append("?token=").append(token);
            sb.append("&ts=").append(ts);

            result.setCode(200);
            result.setMessage("获取成功!");
            result.setResult(sb.toString());
        }
        return result;
    }

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表