• Spring Boot 3.x集成FastDFS记录


    最近在做一个课程,需要用讲一下SpringBoot 使用文件上传的功能,选择了FastDFS作为文件存储OSS。Spring Boot是最新的3.3.0版本,JDK版本是17,中间有一些坑,下面记录一下。

    
        org.springframework.boot
        spring-boot-starter-parent
        3.3.0
         
    
    
        17
    
    

    一,安装FastDFS

    FastDFS高可用集群架构配置搭建及使用_fdfs 集群 使用-CSDN博客

    二,集成

    1,引入pom

    
    
        com.github.tobato
        fastdfs-client
        1.27.2
        
           
              org.slf4j
              slf4j-api
           
           
              org.slf4j
              jcl-over-slf4j
           
           
              ch.qos.logback
              logback-classic
           
           
              org.springframework.boot
              spring-boot-starter-logging
           
        
    
    
    
        javax.annotation
        javax.annotation-api
        1.3.2
    
    

    2,导入FastDFS配置

    fdfs:
      open: true
      so-timeout: 1501
      connect-timeout: 601
      thumb-image: #缩略图生成参数
        width: 150
        height: 150
      tracker-list: #TrackerList参数,支持多个
        - 10.250.112.141:22122
    file:
      domain: http://10.250.112.143:8888/

    3,工具类

    (1)FastDFSClient
    import com.github.tobato.fastdfs.domain.fdfs.MetaData;
    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 jakarta.annotation.Resource;
    import jakarta.servlet.ServletOutputStream;
    import jakarta.servlet.http.HttpServletResponse;
    import org.apache.commons.io.FilenameUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.net.URLEncoder;
    import java.util.HashSet;
    import java.util.Set;
    
    @Component
    public class FastDFSClient {
        @Resource
        private FastFileStorageClient fastFileStorageClient;
    
        /**
         * 上传
         *
         * @param file
         * @return
         * @throws IOException
         */
        public StorePath upload(MultipartFile file) throws IOException {
            // 设置文件信息
            Set mataData = new HashSet<>();
            mataData.add(new MetaData("author", "fastdfs"));
            mataData.add(new MetaData("description", file.getOriginalFilename()));
            // 上传
            StorePath storePath = fastFileStorageClient.uploadFile(
                file.getInputStream(), file.getSize(),
                FilenameUtils.getExtension(file.getOriginalFilename()),
                null);
            return storePath;
        }
    
        /**
         * 上传文件
         *
         * @param file
         * @return
         * @throws FileNotFoundException
         */
        public String uploadFile(String file) throws FileNotFoundException {
            File file1 = new File(file);
            if (!file1.exists()) {
                return null;
            }
    
            FileInputStream fileInputStream = new FileInputStream(file1);
            // 上传文件和Metadata
            StorePath path = fastFileStorageClient.uploadFile(fileInputStream, file1.length(), FilenameUtils.getExtension(file1.getName()),
                null);
            return path.getFullPath();
        }
    
        /**
         * 上传文件
         *
         * @param file
         * @return
         * @throws IOException
         */
        public String uploadFile(File file) throws IOException {
            if (file == null) {
                return null;
            }
    
            FileInputStream fileInputStream = new FileInputStream(file);
            // 上传文件和Metadata
            StorePath path = fastFileStorageClient.uploadFile(fileInputStream, file.length(), FilenameUtils.getExtension(file.getName()),
                null);
            fileInputStream.close();
            return path.getFullPath();
        }
    
        /**
         * 删除
         *
         * @param path
         */
        public void delete(String path) {
            fastFileStorageClient.deleteFile(path);
        }
    
        /**
         * 删除
         *
         * @param group
         * @param path
         */
        public void delete(String group, String path) {
            fastFileStorageClient.deleteFile(group, path);
        }
    
        /**
         * 文件下载
         *
         * @param path     文件路径,例如:/group1/path=M00/00/00/itstyle.png
         * @param filename 下载的文件命名
         * @return
         */
        public void download(String path, String filename, HttpServletResponse response) throws IOException {
            // 获取文件
            StorePath storePath = StorePath.parseFromUrl(path);
            if (StringUtils.isBlank(filename)) {
                filename = FilenameUtils.getName(storePath.getPath());
            }
            byte[] bytes = fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
            response.reset();
            response.setContentType("applicatoin/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            ServletOutputStream out = response.getOutputStream();
            out.write(bytes);
            out.close();
        }
    }
    
    (2)FastDFSConfig
    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;
    
    @Configuration
    @Import(FdfsClientConfig.class)
    // 解决jmx重复注册bean的问题
    @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
    public class FastDFSConfig {
    }
    (3)FastDfsStorePath
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import lombok.Data;
    
    @Data
    public class FastDfsStorePath {
        private String group;
        private String path;
        private String fullPath;
        private String fileUrl;
    
        public FastDfsStorePath(StorePath storePath) {
            this.group = storePath.getGroup();
            this.path = storePath.getPath();
            this.fullPath = storePath.getFullPath();
        }
    }

    4,上传文件接口

    @Value("${file.domain}")
    private String fileDomain;
    @Operation(summary = "上传文件")
    @PostMapping("/file")
    @ResponseBody
    public RestResponse updateFile(@RequestParam("file") MultipartFile file) throws IOException {
        log.info("=====>文件名: {}", file.getOriginalFilename());
        StorePath storePath = fastDFSClient.upload(file);
        FastDfsStorePath fastDfsStorePath = new FastDfsStorePath(storePath);
        fastDfsStorePath.setFileUrl(fileDomain + storePath.getFullPath());
        return RestResponse.success(fastDfsStorePath);
    }

    接口返回

    {

        "code": 200,

        "message": null,

        "data": {

            "group": "group1",

            "path": "M00/00/01/CpaE3mZer6WANEKKADTPweiDcA8273.png",

            "fullPath": "group1/M00/00/01/CpaE3mZer6WANEKKADTPweiDcA8273.png",

            "fileUrl": "http://10.250.112.143:8888/group1/M00/00/01/CpaE3mZer6WANEKKADTPweiDcA8273.png"

        },

        "requestId": null,

        "success": true

    }

    完毕!

  • 相关阅读:
    Exoplayer源码解析2
    重学JavaSE 第15章 : File类、IO流介绍、文件流、缓冲流、转换流、对象流等
    JAVA SPI
    Go 并发编程 - runtime 协程调度(三)
    七、golang基础之interface与类型断言
    (网络编程)模拟客户端与服务端的交互
    mysql全文索引
    基于SEIRD和元胞自动机(CA)模型的传染病发展趋势预测
    LeetCode刷题day24||回溯算法理论基础&&77. 组合--回溯
    基于学生成绩管理系统(附源代码及数据库)
  • 原文地址:https://blog.csdn.net/wangerrong/article/details/139441224