fastdfs_client开源项目的作者是tobato
项目地址:https://github.com/tobato/FastDFS_Client
它是一个针对fastDFS的java客户端第三方组件,在原作者YuQing与yuqih发布的java客户端基础上进行了大量重构工作,对于开发者而言
可以更便捷、优雅的调用FastDFS的服务。
如何使用fastdfs_client?
本项目是基于SpringBoot2.x框架的,具体操作如下:
1.在项目Pom当中加入依赖
Maven依赖为
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
2.将Fdfs配置引入项目
在Maven当中配置依赖以后,SpringBoot项目将会自动导入FastDFS依赖
FastDFS-Client 1.26.4版本以前引入方式
将FastDFS-Client客户端引入本地化项目的方式非常简单,在SpringBoot项目/src/[com.xxx.主目录]/conf
当中配置
/**
* 导入FastDFS-Client组件
*
* @author tobato
*
*/
@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {
// 导入依赖组件
}
只需要一行注解 @Import(FdfsClientConfig.class)就可以拥有带有连接池的FastDFS Java客户端了。
3.在application.yml当中配置Fdfs相关参数
# ===================================================================
# 分布式文件系统FDFS配置
# ===================================================================
fdfs:
so-timeout: 1501
connect-timeout: 601
thumb-image: #缩略图生成参数
width: 150
height: 150
tracker-list: #TrackerList参数,支持多个
- 192.168.1.105:22122
- 192.168.1.106:22122
4.通过FastDFS-Client的接口服务对文件进行相应操作
首先编写一个工具类FastdfsClientUtil用于封装相应的操作,分别实现:
-
上传文件
-
下载文件
-
删除文件
-
上传图片,并生成缩略图
package org.learn.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 org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* FastDFS工具类
*/
@Component
public class FastdfsClientUtil {
@Autowired
private FastFileStorageClient fastFileStorageClient;
@Autowired
private ThumbImageConfig thumbImageConfig;
/**
* 上传文件
*
* @param file 文件对象
* @return 文件访问地址
* @throws IOException
*/
public String uploadFile(MultipartFile file) throws IOException {
StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(),
file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()), null);
return storePath.getFullPath();
}
/**
* 下载文件
*
* @param fileUrl 文件URL
* @return 文件字节
* @throws IOException
*/
public byte[] downloadFile(String fileUrl) throws IOException {
String group = fileUrl.substring(0, fileUrl.indexOf("/"));
String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
DownloadByteArray downloadByteArray = new DownloadByteArray();
byte[] bytes = fastFileStorageClient.downloadFile(group, path,
downloadByteArray);
return bytes;
}
/**
* 删除文件
*
* @Param fileUrl 文件访问地址
*/
public void deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return;
}
try {
StorePath storePath = StorePath.parseFromUrl(fileUrl);
fastFileStorageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (FdfsUnsupportStorePathException e) {
e.printStackTrace();
}
}
/**
* 上传图片,并生成缩略图
*/
public Map<String, String> uploadImageAndCrtThumbImage(MultipartFile file) throws IOException {
Map<String, String> map = new HashMap<>();
StorePath storePath = fastFileStorageClient.uploadImageAndCrtThumbImage(file.getInputStream(),
file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()), null);
// 这里需要一个获取从文件名的能力,所以从文件名配置以后就最好不要改了
String slavePath = thumbImageConfig.getThumbImagePath(storePath.getPath());
map.put("path", storePath.getFullPath()); //原路径图片地址
map.put("slavePath", slavePath); //缩略图图片地址
return map;
}
}
5.编写Controller类
package org.learn.controller;
import org.learn.utils.FastdfsClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
/**
* FastDFS上传文件控制器
*/
@Controller
public class FdfsClientController {
private static Logger logger = LoggerFactory.getLogger(FdfsClientController.class);
@Autowired
private FastdfsClientUtil fastdfsClientUtil;
/**
* 上传文件
*
* @param file
* @return
*/
@RequestMapping("/uploadFile")
public String uploadFile(@RequestParam("file") MultipartFile file, Model view) {
try {
String path = fastdfsClientUtil.uploadFile(file);
System.out.println("path:" + path);
view.addAttribute("uri", path);
} catch (IOException e) {
e.printStackTrace();
}
return "index";
}
/**
* 下载文件
*
* @param filePath
* @param response
* @return
*/
@RequestMapping("/downloadFile")
public void downloadFile(@RequestParam("filePath") String filePath, HttpServletResponse response) {
int index = filePath.lastIndexOf("/");
String fileName = filePath.substring(index + 1);
try {
byte[] bytes = fastdfsClientUtil.downloadFile(filePath);
InputStream inputStream = new ByteArrayInputStream(bytes);
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 (IOException e) {
e.printStackTrace();
}
}
/**
* 删除文件
*
* @param filePath
* @return
*/
@RequestMapping("/deleteFile")
@ResponseBody
public String deleteFile(@RequestParam("filePath") String filePath) {
fastdfsClientUtil.deleteFile(filePath);
return "删除文件成功";
}
/**
* 上传图片,并且生成缩略图
*/
@RequestMapping("/uploadImageAndCrtThumbImage")
public String uploadImageAndCrtThumbImage(@RequestParam("file") MultipartFile file, Model view) {
try {
//上传图片,并且生成缩略图的方法
Map<String, String> map = fastdfsClientUtil.uploadImageAndCrtThumbImage(file);
view.addAttribute("uri", map.get("path"));//原图片地址
view.addAttribute("slavePath", map.get("slavePath")); //缩略图地址
} catch (IOException e) {
e.printStackTrace();
}
return "index";
}
}
6.编写上传文件的页面
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello,你已经进入到首页
<span th:text="${uri}"></span>
<form action="/uploadFile" enctype="multipart/form-data" method="post">
文件上传<input type="file" name="file" id="file"/>
<input type="submit" value="提交">
</form>
</body>
</html>
7.演示上传下载操作
演示一个图片的上传、下载、删除、生成缩略图并获取
- 上传文件
访问页面,执行上传操作
上传成功后,页面返回文件的地址,下面我们在浏览器直接访问该图片,记得带上文件服务器的IP:端口,如果能正常显示图片,表示上传成功
-
下载文件
直接在浏览器发起下载文件的请求,地址如下
http://localhost:8080/downloadFile?filePath=group1/M00/00/00/wKgBa18vqWCAakxaAAW8VIh03qE499.png
-
删除文件
在浏览器执行文件删除操作,地址如下:
http://localhost:8080/deleteFile?filePath=group1/M00/00/00/wKgBa18vqWCAakxaAAW8VIh03qE499.png
- 生成缩略图并获取
首选将首页的上传的请求更改为上传图片,并且生成缩略图的接口,/uploadImageAndCrtThumbImage
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello,你已经进入到首页
<span th:text="${uri}"></span>
<form action="/uploadImageAndCrtThumbImage" enctype="multipart/form-data" method="post">
文件上传<input type="file" name="file" id="file"/>
<input type="submit" value="提交">
</form>
</body>
</html>
执行上传操作后,文件服务器端将生成对应的缩略图文件,我们请求的地址后面只需要带上缩略图后缀,如:
源图 http://192.168.1.107:8085/M00/00/17/rBEAAl33pQaAWNQNAAHYvQQn-YE374.jpg
缩略图 http://192.168.1.107:8085/M00/00/17/rBEAAl33pQaAWNQNAAHYvQQn-YE374_150x150.jpg