环境搭建
- 搭建 Tracker
docker run -d --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
- 搭建 Storage (注意修改TRACKER_SERVER IP)
docker run -d --network=host --name storage -e TRACKER_SERVER=192.168.0.102:22122 -v /var/fdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage
- 配置修改 进入Stroage 容器 /etc/fdfs/storage.conf 把 http.server_port=8888改为任意端口(我这里使用80端口)
- 修改nginx配置 路径/usr/local/nginx/conf nginx.conf 改为和server_port端口一样 然后保存重启容器
server {
listen 80;
server_name localhost;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- 测试:往宿主机/var/fdfs/storage/a.jpg 放一张照片 然后进入stroage 容器/var/fdfs/storage/目录下,运行下面命令 生成图片路径(访问,检查是否放开80端口)
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf a.jpg
Spring Boot整个FastDFS
- 引入依赖
<!-- fastdfs文件代码 -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
- 添加配置信息(请检查端口是否开放)
fdfs:
soTimeout: 15000 #socket连接超时时长
connectTimeout: 15000 #连接tracker服务器超时时长
reqHost: 192.168.0.102 #nginx访问地址
reqPort: 80 #nginx访问端口
thumbImage: #缩略图生成参数,可选
width: 150
height: 150
trackerList: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port
- 192.168.0.102:22122
- 创建FastDFS客户端配置类
package com.pig4cloud.pig.client.util;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadCallback;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@Component
public class FastDFSClientUtil {
@Value("${fdfs.reqHost}")
private String reqHost;
@Value("${fdfs.reqPort}")
private String reqPort;
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private ThumbImageConfig thumbImageConfig; //创建缩略图 , 缩略图访问有问题,暂未解决
public String uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile((InputStream)file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
String path = thumbImageConfig.getThumbImagePath(storePath.getPath()) ;
System.out.println("thumbImage :" + path); // 缩略图访问有问题,暂未解决
return getResAccessUrl(storePath);
}
public void delFile(String filePath) {
storageClient.deleteFile(filePath);
}
public InputStream download(String groupName, String path ) {
InputStream ins = storageClient.downloadFile(groupName, path, new DownloadCallback<InputStream>(){
@Override
public InputStream recv(InputStream ins) throws IOException {
// 将此ins返回给上面的ins
return ins;
}}) ;
return ins ;
}
/**
* 封装文件完整URL地址
* @param storePath
* @return
*/
private String getResAccessUrl(StorePath storePath) {
String fileUrl = "http://" + reqHost + ":" + reqPort + "/" + storePath.getFullPath();
return fileUrl;
}
}
- 在启动类上面导入配置注解
@Import(FdfsClientConfig.class) // 导入FastDFS-Client组件
- 创建Controller代码
package com.pig4cloud.pig.client.controller.common;
import com.google.common.collect.Maps;
import com.pig4cloud.pig.client.util.FastDFSClientUtil;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.annotation.Inner;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@RestController
@RequestMapping("/common")
@Inner(value = false)
public class UploadController {
@Autowired
private FastDFSClientUtil dfsClient;
@PostMapping("/upload")
public R<?> fdfsUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
try {
HashMap<String, String> objectObjectHashMap = Maps.newHashMap();
String fileUrl = dfsClient.uploadFile(file);
objectObjectHashMap.put("url", fileUrl);
return R.ok(objectObjectHashMap);
} catch (IOException e) {
e.printStackTrace();
return R.failed("上传异常");
}
}
@RequestMapping("/download")
public void download(String filePath, HttpServletRequest request, HttpServletResponse response) throws IOException {
String[] paths = filePath.split("/");
String groupName = null;
for (String item : paths) {
if (item.indexOf("group") != -1) {
groupName = item;
break;
}
}
String path = filePath.substring(filePath.indexOf(groupName) + groupName.length() + 1, filePath.length());
InputStream input = dfsClient.download(groupName, path);
//根据文件名获取 MIME 类型
String fileName = paths[paths.length - 1];
System.out.println("fileName :" + fileName); // wKgIZVzZEF2ATP08ABC9j8AnNSs744.jpg
String contentType = request.getServletContext().getMimeType(fileName);
String contentDisposition = "attachment;filename=" + fileName;
// 设置头
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", contentDisposition);
// 获取绑定了客户端的流
ServletOutputStream output = response.getOutputStream();
// 把输入流中的数据写入到输出流中
IOUtils.copy(input, output);
input.close();
}
/**
* @param fileName group1/M00/00/00/wKgIZVzZaRiAZemtAARpYjHP9j4930.jpg
* @param request
* @param response
* @return
*/
@RequestMapping("/deleteFile")
public R<?> delFile(String filePath, HttpServletRequest request, HttpServletResponse response) {
try {
dfsClient.delFile(filePath);
return R.ok("删除成功");
} catch (Exception e) {
return R.failed("删除异常");
}
}
}