一、FastDFS的搭建
参考https://www.cnblogs.com/chiangchou/p/fastdfs.html这篇博文。需要注意的是如果在编辑 /etc/hosts时有所改变,需要在后面相应的配置文件做出改变,笔者本人在 Nginx部分时配置nginx.conf时未及时修改,所以出现了错误,希望读者在修改相关配置文件时多加注意。
网上关于FastDFS的原理介绍的很多,在此不多加赘述。
二、SpringBoot整合FastDFS
1.项目结构
3.在 pom.xml 添加 Maven 依赖
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
2.项目配置文件(application.yml)
#搭建FastDFS服务器的ip地址与FastDFS中Tracker(跟踪服务器的端口)
fdfs.trackerList=192.168.1.66:22122
## 连接超时时间
fdfs.connect-timeout=5000
## 读取inputsream阻塞时间
fdfs.so-timeout=3000
## 连接池最大数量
fdfs.pool.max-total=200
## 每个tracker地址的最大连接数
fdfs.pool.max-total-per-key=20
## 连接耗尽时等待获取连接的最大毫秒数
fdfs.pool.max-wait-millis=25000
## 缩略图相关配置(如果此处上传文件是图片,需要用到这个配置)
fdfs.thumbImage.height=150
fdfs.thumbImage.width=150
3.conf目录下的ComponetImport类
package com.wt.fastdfs222.conf;
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;
/**
* @author: Lucifer
* @create: 2018-11-10 23:15
* @description:导入FastDFS-Client组件
**/
@Configuration
@Import(FdfsClientConfig.class)
/**
* 解决jmx重复注册bean的问题
*/
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {
// 导入依赖组件
}
4.utils 目录下的 FileDfsUtil 类(即FastDFS提供的工具类)
package com.wt.fastdfs222.utils;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.wt.fastdfs222.controller.FdfsClientController;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
@Component
public class FileDfsUtil {
private static Logger logger = LoggerFactory.getLogger(FdfsClientController.class);
@Autowired
private FastFileStorageClient storageClient;
/**
* 上传文件
* @param file
* @return
* @throws Exception
*/
public String upload(MultipartFile file) throws Exception {
//文件名
String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
// 文件扩展名
String ext = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), fileName, null);
String path = storePath.getFullPath();
return path;
}
/**
* 下载文件
* @param groupName 组名
* @param path 文件路径
* @return
*/
public byte[] downloadFile(String groupName,String path) {
try {
byte[] bytes = storageClient.downloadFile(groupName, path, new DownloadByteArray());
return bytes;
} catch (FdfsUnsupportStorePathException e) {
System.out.println(e.getMessage());
return null;
}
}
}
注:笔者在此处只写了上传文件和下载文件的工具类。
5. controller 目录下的 FdfsClientController 类
package com.wt.fastdfs222.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.wt.fastdfs222.utils.FileDfsUtil;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
@RestController
public class FdfsClientController {
private static Logger logger = LoggerFactory.getLogger(FdfsClientController.class);
@Autowired
FileDfsUtil fastDFSClientUtil;
/**
* 上传文件
* @param file
* @return
*/
@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
public String uploadFile(MultipartFile file) {
try {
// 获取原文件名
String origFileName = file.getOriginalFilename();
logger.info("原始文件名:{}", origFileName);
// 获取扩展名
String extName = origFileName.substring(origFileName.lastIndexOf(".") + 1);
logger.info("原始文件扩展名:{}", extName);
// 获取文件存储路径
String uri = fastDFSClientUtil.upload(file);
logger.info("返回的文件存储路径:{}", uri);
return uri;
} catch (Exception e) {
logger.error(e.toString(), e);
return null;
}
}
/**
* 下载文件
* @param groupName
* @param fileId
* @return
*/
@RequestMapping("/downloadFile")
public void downloadFile(@RequestParam("groupName") String groupName,
@RequestParam("fileId") String fileId, HttpServletResponse response) {
try {
// 获取文件名
int index = fileId.lastIndexOf("/");
String fileName = fileId.substring(index + 1);
/**
* 参数格式:
* groupName: group1
* fileId: M00/00/00/wKjlj15o9rGAP5MkAACpl5L2fqw700.jpg
*/
byte[] fileByte = fastDFSClientUtil.downloadFile(groupName, fileId);
InputStream inputStream = new ByteArrayInputStream(fileByte);
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
byte[] buff = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(inputStream);
OutputStream os = response.getOutputStream();
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
os.close();
bis.close();
logger.info("Download successfully!");
} catch (Exception e) {
logger.error(e.toString(), e);
}
}
}
三、结束
至此,项目即可运行,相关结果可在postman中进行验证。
文件下载同理,参数有区别,不再赘述。