SpringBoot集成基于tobato的fastdfs-client实现文件上传下载和删除

1. 简介

  基于tobato的fastdfs-client是一个功能完善的FastDFS客户端工具,它是在FastDFS作者YuQing发布的客户端基础上进行了大量的重构,提供了上传、下载、删除、生成缩略图等API。

2. 安装FastDFS

  Docker部署FastDFS(附示例代码)

3. 示例代码

  • 创建工程
  • 修改pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.c3stones</groupId>
	<artifactId>spirng-boot-fastdfs-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spirng-boot-fastdfs-demo</name>
	<description>Spring Boot FastDFS Demo</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.8.RELEASE</version>
		<relativePath />
	</parent>

	<dependencies>
		<dependency>
			<groupId>com.github.tobato</groupId>
			<artifactId>fastdfs-client</artifactId>
			<version>1.26.6</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
  • 创建配置文件application.yml
#fastdfs 配置
fdfs:
  # 读取时间
  so-timeout: 1500
  # 连接超时时间
  connect-timeout: 600
  # 缩略图
  thumb-image:
    width: 150
    height: 150
  # Tracker服务
  tracker-list:
    - 192.168.0.100:22122
  • 创建配置类
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;

/**
 * FastDFS Client配置
 * 
 * @author CL
 *
 */
@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FdfsConfig {

}
  • 创建包装类
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

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 com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.service.FastFileStorageClient;

/**
 * FastDFS客户端包装类
 * 
 * @author CL
 *
 */
@Component
public class FdfsClientWrapper {

	@Autowired
	private FastFileStorageClient fastFileStorageClient;

	public String uploadFile(MultipartFile file) throws IOException {
		if (file != null) {
			byte[] bytes = file.getBytes();
			long fileSize = file.getSize();
			String originalFilename = file.getOriginalFilename();
			String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
			return this.uploadFile(bytes, fileSize, extension);
		}
		return null;
	}

	/**
	 * 文件上传
	 * 
	 * @param bytes     文件字节
	 * @param fileSize  文件大小
	 * @param extension 文件扩展名
	 * @return 返回文件路径(卷名和文件名)
	 */
	public String uploadFile(byte[] bytes, long fileSize, String extension) {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		// 元数据
		Set<MetaData> metaDataSet = new HashSet<MetaData>();
		metaDataSet.add(new MetaData("dateTime", LocalDateTime.now().toString()));
		StorePath storePath = fastFileStorageClient.uploadFile(bais, fileSize, extension, metaDataSet);
		return storePath.getFullPath();
	}

	/**
	 * 下载文件
	 * 
	 * @param filePath 文件路径
	 * @return 文件字节
	 * @throws IOException
	 */
	public byte[] downloadFile(String filePath) throws IOException {
		byte[] bytes = null;
		if (StringUtils.isNotBlank(filePath)) {
			String group = filePath.substring(0, filePath.indexOf("/"));
			String path = filePath.substring(filePath.indexOf("/") + 1);
			DownloadByteArray byteArray = new DownloadByteArray();
			bytes = fastFileStorageClient.downloadFile(group, path, byteArray);
		}
		return bytes;
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath 文件路径
	 */
	public void deleteFile(String filePath) {
		if (StringUtils.isNotBlank(filePath)) {
			fastFileStorageClient.deleteFile(filePath);
		}
	}

}
  • 创建文件上传Controller
import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.c3stones.wapper.FdfsClientWrapper;

/**
 * 文件上传Controller
 * 
 * @author CL
 *
 */
@Controller
public class FileUploadController {

	private static Logger log = LoggerFactory.getLogger(FileUploadController.class);

	@Autowired
	private FdfsClientWrapper fdfsClientWrapper;

	/**
	 * 进入上传页面
	 * 
	 * @return 路径
	 */
	@RequestMapping(value = "/")
	public String form() {
		return "form";
	}

	/**
	 * 上传文件
	 * 
	 * @param file 文件
	 * @return 文件路径
	 */
	@RequestMapping(value = "upload")
	@ResponseBody
	public String uploadFile(MultipartFile file) {
		String filePath = null;
		try {
			filePath = fdfsClientWrapper.uploadFile(file);
		} catch (IOException e) {
			log.error("上传文件异常:{}", e);
			return "上传文件失败";
		}
		return filePath;
	}

	/**
	 * 下载文件
	 * 
	 * @param filePath 文件路径
	 * @return
	 */
	@RequestMapping(value = "download")
	public void downloadFile(String filePath, HttpServletResponse response) {
		ServletOutputStream outputStream = null;
		try {
			byte[] bytes = fdfsClientWrapper.downloadFile(filePath);
			String fileName = "fdfs.jpg";
			response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
			response.setCharacterEncoding("UTF-8");
			if (bytes != null) {
				outputStream = response.getOutputStream();
				outputStream.write(bytes);
				outputStream.flush();
			}
		} catch (IOException e) {
			log.debug("下载文件输出流异常:{}", e);
		} finally {
			try {
				if (outputStream != null) {
					outputStream.close();
				}
			} catch (IOException e) {
				log.debug("下载文件关闭流异常:{}", e);
			}
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath 文件路径
	 * @return 删除结果
	 */
	@RequestMapping(value = "delete")
	@ResponseBody
	public String deleteFile(String filePath) {
		fdfsClientWrapper.deleteFile(filePath);
		return "删除成功";
	}

}
  • 创建启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 * 
 * @author CL
 *
 */
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}
  • 在resource下创建templates/form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
	<form action="/upload" method="post" enctype="multipart/form-data">
		选择文件:<input type="file" name="file"><br /> 
		<input type="submit" value="提交">
	</form>
</body>
</html>
  • 启动项目

4. 测试

5. 项目地址

  spirng-boot-fastdfs-demo

posted @ 2020-08-10 21:24  C3Stones  阅读(2596)  评论(0编辑  收藏  举报