1、背景
在前一节中,我们搭建了一个单机版的fastdfs
服务,此处我们将fastdfs与springboot进行整合,实现文件的上传和下载。
2、整合步骤
2.1、引入依赖
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
2.2、引入fastdfs配置
fdfs:
so-timeout: 2000 # 读取时间
connect-timeout: 1000 # 连接超时时间
thumb-image: # 生成缩略图
height: 150 # 缩略图高度
width: 150 # 缩略图宽度
tracker-list: # tracker 服务器地址
- 192.168.121.137:22122
web-server-url: http://192.168.121.137:8888/ # storage 服务器上nginx的地址
pool: # 可参考 ConnectionPoolConfig
#从池中借出的对象的最大数目(配置为-1表示不限制)
max-total: -1
#获取连接时的最大等待毫秒数(默认配置为5秒)
max-wait-millis: 5000
#每个key最大连接数 key配置的是连接服务端的地址(IP+端口)连接情况,如果有连接不够用的情况可以调整以上参数
max-total-per-key: 50
#每个key对应的连接池最大空闲连接数
max-idle-per-key: 10
#每个key对应的连接池最小空闲连接数
min-idle-per-key: 5
#向调用者输出“连接”资源时,是否检测有效性
test-on-borrow: true
2.3 编写文件上传和下载接口
package com.huan.fastdfs.controller;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
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 lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* fastdfs 文件上传和下载控制器
* @author huan.fu
* @date 2022/10/8 - 20:24
*/
@RestController
@AllArgsConstructor
@RequestMapping("fdfs")
@Slf4j
public class FastdfsController {
private final FastFileStorageClient fastFileStorageClient;
private final FdfsWebServer fdfsWebServer;
/**
* 上传文件
*/
@PostMapping("uploadFile")
public List<String> uploadFile(MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
// 获取文件扩展名
String extension = FilenameUtils.getExtension(fileName);
// 文件元数据信息
Set<MetaData> metaData = new HashSet<>(4);
metaData.add(new MetaData("fileName",fileName));
// 上传文件
StorePath storePath = fastFileStorageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), extension, metaData);
log.info("文件上传路径:[{}]",storePath.getFullPath());
String viewPath = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
log.info("可访问路径:[{}]",viewPath);
extension = FilenameUtils.getExtension(viewPath);
String xthumbPath = viewPath.replace("." + extension, "")+"_150x150."+extension;
log.info("缩略图路径:[{}]",xthumbPath);
List<String> result = new ArrayList<>(3);
result.add(viewPath);
result.add(xthumbPath);
result.add(storePath.getFullPath());
return result;
}
/**
* 下载文件
*/
@GetMapping("download")
public void downloadFile(String filePath, HttpServletResponse response) throws IOException {
log.info("需要下载的文件:[{}]",filePath);
String group = filePath.substring(0, filePath.indexOf("/"));
String path = filePath.substring(filePath.indexOf("/") + 1);
Set<MetaData> metadata = fastFileStorageClient.getMetadata(group, path);
String fileName = metadata.iterator().next().getValue();
byte[] bytes = fastFileStorageClient.downloadFile(group, path, new DownloadByteArray());
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, Charsets.UTF_8.displayName()));
IOUtils.write(bytes,response.getOutputStream());
}
}
2.4 测试文件上传
从上图中可以,实现了文件的上传和缩略图的生成。