如果应用是在集群部署,如果文件存储需要共享要通过linux的nfs服务来实现共享,或者把文件存储在分布式文件存储系统里面,例如FastDFS,minio,本章讲解集成FastDFS实现分布式文件存储。
FastDFS环境搭建请参考https://dominick-li.blog.csdn.net/article/details/121529247
com.github.tobato
fastdfs-client
1.27.2
编辑application.yml文件
spring:
application:
name: fastdfs
servlet:
multipart:
enabled: true
max-file-size: 10MB
max-request-size: 20MB
fdfs:
# 连接超时 默认值(60)
connect-timeout: 6000
# 读取时间 默认值(60)
so-timeout: 6000
# 生成缩略图参数
thumb-image:
enabled: true
width: 250
height: 150
#Tracte服务的ip和端口,多个可以用逗号隔开,或者通过nginx做一个负载均衡然后配置一个即可。
tracker-list: 192.168.94.128:22122
server:
port: 8024
下面定义了上传文件,下载文件,删除文件的方法.
package com.ljm.boot.fastdfs.config;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
/**
* @author Dominick Li
* @CreateTime 2020/3/29 17:56
* @description 操作dfs 工具类
**/
@Component
public class FileDfsUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FileDfsUtil.class);
@Resource
private FastFileStorageClient storageClient;
@Value("${fdfs.thumb-image.enabled}")
private boolean thumbEnabled;
/**
* 上传文件
*/
public String upload(MultipartFile multipartFile) throws Exception {
String originalFilename = multipartFile.getOriginalFilename().
substring(multipartFile.getOriginalFilename().
lastIndexOf(".") + 1);
StorePath storePath = null;
if (thumbEnabled) {
//上传文件并生成缩略图,如果返回的图片名称 test.jpg,则缩略图的名称是test_宽x高.jpg,例如test_250x150.jpg
storePath = this.storageClient.uploadImageAndCrtThumbImage(multipartFile.getInputStream(), multipartFile.getSize(), originalFilename, null);
} else {
//上传文件
storePath = this.storageClient.uploadFile(multipartFile.getInputStream(), multipartFile.getSize(), originalFilename, null);
}
return storePath.getFullPath();
}
/**
* 删除文件
*/
public void deleteFile(String fileUrl, boolean hasThumbnail) {
try {
StorePath storePath = StorePath.parseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
if (hasThumbnail) {
//删除缩略图
String[] arr = fileUrl.split("\\.");
String thumbnailFileUrl = arr[0] +"_"+ width + "x" + height + "." + arr[1];
storePath = StorePath.parseFromUrl(thumbnailFileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
}
} catch (Exception e) {
LOGGER.info(e.getMessage());
}
}
/**
* 下载文件
*/
public byte[] downloadFile(String fileUrl) {
StorePath storePath = StorePath.parseFromUrl(fileUrl);
return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
}
}
package com.ljm.boot.fastdfs.controller;
import com.ljm.boot.fastdfs.config.FileDfsUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Dominick Li
* @CreateTime 2020/3/29 17:56
* @description 测试上传下载和删除
**/
@RestController
@RequestMapping("/file")
public class FileController {
@Resource
private FileDfsUtil fileDfsUtil;
/**
* 测试FastDFS文件上传
* 如果要生成缩略图,则缩略图的名字为图片后缀加_图片宽*高
* 使用接口返回的名称和nginx的访问地址拼接即可在浏览器访问 http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
* 如果正常图片是group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg 则缩略图为 group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436_250x150.jpg
*/
@PostMapping(value = "/")
public ResponseEntity<String> uploadFile(MultipartFile file) {
String result;
try {
String path = fileDfsUtil.upload(file);
if (!StringUtils.isEmpty(path)) {
result = path;
} else {
result = "上传失败";
}
} catch (Exception e) {
e.printStackTrace();
result = "服务异常";
}
return ResponseEntity.ok(result);
}
/**
* 文件删除
* http://localhost:8024/file/fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg&hasThumbnail=true
* @param fileUrl 上传接口返回的文件名
* @param hasThumbnail 是否有缩略图
*/
@DeleteMapping(value = "/")
public ResponseEntity<String> deleteByPath(String fileUrl,@RequestParam(value = "hasThumbnail",required = false,defaultValue = "false") boolean hasThumbnail) {
fileDfsUtil.deleteFile(fileUrl,hasThumbnail);
return ResponseEntity.ok("SUCCESS");
}
/**
* 文件下载
* http://localhost:8024/download?fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
* @param fileUrl 上传接口返回的文件名
*/
@GetMapping("/")
public void downLoad(@RequestParam String fileUrl, HttpServletResponse response) throws IOException {
// 获取文件
byte[] bytes = fileDfsUtil.downloadFile(fileUrl);
String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
response.reset();
response.setContentType("application/x-download");
response.addHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
response.getOutputStream().write(bytes);
response.getOutputStream().close();
}
}
通过postman调用localhost:8024/file/接口进行文件上传
把nginx的访问地址和文件名拼接即可访问图片
访问原图: http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
访问缩略图: http://192.168.94.128:9999/group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436_250x150.jpg
浏览器访问: http://localhost:8024/file/?fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
可以看到浏览器左下角有一张图片下载成功.
通过postman请求接口,请求类型选择DELETE
http://localhost:8024/file/fileUrl=group1/M00/00/00/wKhegGGeylOAJx8yAB7ib2v_DBQ436.jpg
删除成功再次通过浏览器访问图片会发现图片已经找不到了,但是缩略图没有删掉。
gitee代码地址
创作不易,要是觉得我写的对你有点帮助的话,麻烦在gitee上帮我点下 Star
【SpringBoot框架篇】其它文章如下,后续会继续更新。