【SpringBoot框架篇】24.集成FastDFS实现文件的分布式存储

1.简介

如果应用是在集群部署,如果文件存储需要共享要通过linux的nfs服务来实现共享,或者把文件存储在分布式文件存储系统里面,例如FastDFS,minio,本章讲解集成FastDFS实现分布式文件存储。
FastDFS环境搭建请参考https://dominick-li.blog.csdn.net/article/details/121529247

2.添加配置

2.1.在maven的pom.xml中添加fastDfs依赖包

        <!-- FastDFS依赖 -->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>

2.2.修改应用配置文件

编辑application.yml文件

spring:
  application:
    name: fastdfs
  servlet:
    multipart:
      enabled: true
      max-file-size: 10MB
      max-request-size: 20MB
fdfs:
  # 连接超时   默认值(60)
  connect-timeout: 6000
  # 读取时间   默认值(60)
  so-timeout: 6000
  # 生成缩略图参数
  thumb-image:
    enabled: true
    width: 250
    height: 150
  #Tracte服务的ip和端口,多个可以用逗号隔开,或者通过nginx做一个负载均衡然后配置一个即可。  
  tracker-list: 192.168.94.128:22122

server:
  port: 8024

3.添加工具类

下面定义了上传文件,下载文件,删除文件的方法.

package com.ljm.boot.fastdfs.config;

import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;

/**
 * @author Dominick Li
 * @CreateTime 2020/3/29 17:56
 * @description 操作dfs 工具类
 **/
@Component
public class FileDfsUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileDfsUtil.class);

    @Resource
    private FastFileStorageClient storageClient;

    @Value("${fdfs.thumb-image.enabled}")
    private boolean thumbEnabled;

    /**
     * 上传文件
     */
    public String upload(MultipartFile multipartFile) throws Exception {
        String originalFilename = multipartFile.getOriginalFilename().
                substring(multipartFile.getOriginalFilename().
                        lastIndexOf(".") + 1);
        StorePath storePath = null;
        if (thumbEnabled) {
            //上传文件并生成缩略图,如果返回的图片名称 test.jpg,则缩略图的名称是test_宽x高.jpg,例如test_250x150.jpg
            storePath = this.storageClient.uploadImageAndCrtThumbImage(multipartFile.getInputStream(), multipartFile.getSize(), originalFilename, null);
        } else {
            //上传文件
            storePath = this.storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(), originalFilename, null);
        }
        return storePath.getFullPath();
    }


    /**
     * 删除文件
     */
    public void deleteFile(String fileUrl, boolean hasThumbnail) {
        try {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
            if (hasThumbnail) {
                //删除缩略图
                String[] arr = fileUrl.split("\\.");
                String thumbnailFileUrl = arr[0] +"_"+ width + "x" + height + "." + arr[1];
                storePath = StorePath.parseFromUrl(thumbnailFileUrl);
                storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
            }
        } catch (Exception e) {
            LOGGER.info(e.getMessage());
        }
    }

    /**
     * 下载文件
     */
    public byte[] downloadFile(String fileUrl) {
        StorePath storePath = StorePath.parseFromUrl(fileUrl);
        return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
    }
}

4.测试接口编写

package com.ljm.boot.fastdfs.controller;

import com.ljm.boot.fastdfs.config.FileDfsUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Dominick Li
 * @CreateTime 2020/3/29 17:56
 * @description 测试上传下载和删除
 **/
@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private FileDfsUtil fileDfsUtil;

    /**
     * 测试FastDFS文件上传
     * 如果要生成缩略图,则缩略图的名字为图片后缀加_图片宽*高
     * 使用接口返回的名称和nginx的访问地址拼接即可在浏览器访问 http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
     * 如果正常图片是group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg 则缩略图为  group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436_250x150.jpg
     */
    @PostMapping(value = "/")
    public ResponseEntity<String> uploadFile(MultipartFile file) {
        String result;
        try {
            String path = fileDfsUtil.upload(file);
            if (!StringUtils.isEmpty(path)) {
                result = path;
            } else {
                result = "上传失败";
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = "服务异常";
        }
        return ResponseEntity.ok(result);
    }

    /**
     * 文件删除
     * http://localhost:8024/file/fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg&hasThumbnail=true
     * @param fileUrl 上传接口返回的文件名
     * @param hasThumbnail 是否有缩略图
     */
    @DeleteMapping(value = "/")
    public ResponseEntity<String> deleteByPath(String fileUrl,@RequestParam(value = "hasThumbnail",required = false,defaultValue = "false") boolean hasThumbnail) {
        fileDfsUtil.deleteFile(fileUrl,hasThumbnail);
        return ResponseEntity.ok("SUCCESS");
    }

    /**
     * 文件下载
     * http://localhost:8024/download?fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
     * @param fileUrl 上传接口返回的文件名
     */
    @GetMapping("/")
    public void downLoad(@RequestParam String fileUrl, HttpServletResponse response) throws IOException {
        // 获取文件
        byte[] bytes = fileDfsUtil.downloadFile(fileUrl);
        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
        response.reset();
        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        response.getOutputStream().write(bytes);
        response.getOutputStream().close();

    }
}

5.测试

5.1.上传图片

通过postman调用localhost:8024/file/接口进行文件上传
在这里插入图片描述
把nginx的访问地址和文件名拼接即可访问图片
访问原图: http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
访问缩略图: http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436_250x150.jpg
在这里插入图片描述
在这里插入图片描述

5.2.下载图片

浏览器访问: http://localhost:8024/file/?fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
可以看到浏览器左下角有一张图片下载成功.
在这里插入图片描述

5.3.删除图片

通过postman请求接口,请求类型选择DELETE
http://localhost:8024/file/fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
在这里插入图片描述
删除成功再次通过浏览器访问图片会发现图片已经找不到了,但是缩略图没有删掉。
在这里插入图片描述

6.项目配套代码

gitee代码地址

创作不易,要是觉得我写的对你有点帮助的话,麻烦在gitee上帮我点下 Star

【SpringBoot框架篇】其它文章如下,后续会继续更新。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皓亮君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值