在一个无论什么样的系统中,文件上传/下载是一个不可或缺的基础功能。在一个比较小的单体项目中,我们不会去单独为文件的存储开辟一个服务器,但是随着我们项目的一步一步扩展从ftp,sftp,分布式存储的服务器一步一步发展而来。目前接触过的主流的分布式文件存储FasfDfs服务器和Hdfs服务器。基于目前的能力,我们这里使用了Fastdfs服务器。
这里主要是spirngboot2.x整合fastdfs文件上传以及下载的功能。FastDfs文件服务器的搭建基于Lunix系统,这里参照一个大神搭建过程,亲测搭建完成 搭建Fdfs文件服务器 。
好勒废话不多说直接上代码。
com.github.tobato
fastdfs-client
1.26.5
ch.qos.logback
logback-classic
#分布式文件系统fastDfs
fdfs:
so-timeout: 1501
connect-timeout: 601
thumb-image: #缩略图生成参数
width: 150
height: 150
web-server-url: 192.168.36.136/
tracker-list:
- 192.168.36.136:22122
pool:
max-wait-millis: 102
jmx-name-base: 1
jmx-name-prefix: 1
pool:
max-total: 153
package com.config.fdfs;
/**
* Fdfs分布式文件系统的配置文件,解决JMX重复注册问题,防止Mbean在启动时因为重复注册而导致注册失败
*/
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;
import com.github.tobato.fastdfs.FdfsClientConfig;
@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FdfsConfig {
}
package com.config.fdfs.clent;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
@Service
public class FastFileClient {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FdfsWebServer fdfsWebServer;
//====================文件操作类
// 封装完整URL地址
private String getResAccessUrl(StorePath storePath) {
String fileUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
return fileUrl;
}
public String upload(MultipartFile file) throws Exception {
StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
return getResAccessUrl(storePath);
}
public String upload(File file) throws Exception {
FileInputStream inputStream = new FileInputStream (file);
StorePath storePath = storageClient.uploadFile(inputStream,file.length(), FilenameUtils.getExtension(file.getName()),null);
return getResAccessUrl(storePath);
}
public String upload(String context, String path) throws Exception {
byte[] buff=context.getBytes(Charset.forName("UTF-8"));
ByteArrayInputStream stream = new ByteArrayInputStream(buff);
StorePath storePath = storageClient.uploadFile(stream,buff.length, path,null);
return getResAccessUrl(storePath);
}
public byte[] downLoad(String fileUrl) throws Exception {
String group = fileUrl.substring(0, fileUrl.indexOf("/"));
String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
byte[] bytes = storageClient.downloadFile(group, path, new DownloadByteArray());
return bytes;
}
public void deleteFile(String fileUrl) throws Exception {
if(fileUrl == null || fileUrl.isEmpty()) {
return ;
}
StorePath storePath = StorePath.parseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
}
public void downLoad(String url,String fileName,HttpServletResponse response) throws Exception {
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName="+fileName);// 设置文件名
IOUtils.write(this.downLoad(url), response.getOutputStream());
}
}
到这里,配置就算完成了,可以直接用FastFileClient调用了
在代码里,我们用Clinet的工具类来调用并且同时将数据存储在文件表中,这里使用Aop来减少耦合,具体思路如下:
四:其他功能