Spring Boot 3.x集成FastDFS记录

发布于:2024-06-08 ⋅ 阅读:(146) ⋅ 点赞:(0)

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

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.0</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
    <java.version>17</java.version>
</properties>

一,安装FastDFS

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

二,集成

1,引入pom

<!-- FastDFS Start 如果已经引入了log4j的实现,需要排除掉fastdfs的-->
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.27.2</version>
    <exclusions>
       <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
       </exclusion>
       <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
       </exclusion>
       <exclusion>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
       </exclusion>
       <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
       </exclusion>
    </exclusions>
</dependency>
<!-- 注解@PostConstruct包路径在jdk17是无效的, 需要补充下面的依赖 -->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>
<!-- FastDFS End -->

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<MetaData> 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<FastDfsStorePath> 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

}

完毕!


网站公告

今日签到

点亮在社区的每一天
去签到