SpringBoot结合分布式文件系统FastDFS实现文件上传功能
一、FastDFS文件系统简介
FastDFS源码: Github地址:https://github.com/happyfish100
搭建FastDFS:
参考地址:
https://blog.csdn.net/wlwlwlwl015/article/details/52619851
https://www.cnblogs.com/chiangchou/p/fastdfs.html
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。
Tracker Server:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。
Storage Server:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。
Client:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。
更多关于FastDFS系统的相关知识,请自行查阅。
二、SpringBoot结合FastDFS实现文件上传功能
(1)项目工程目录结构
(2)项目pom.xml配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.26.1-RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.1.1.RELEASE</version> </dependency> </dependencies>
(3)FDS配置文件: fdfs_client.conf:
#以下为你搭建的FastDFS系统的配置信息,请自行修改 connect_timeout = 60 network_timeout = 60 charset = UTF-8 http.tracker_http_port = 8080 http.anti_steal_token = no http.secret_key = 123456 tracker_server = 127.0.0.1:22122
(4)项目部分代码
后台:
(a)FasfDFSClient.java
package com.lhf.springbootfastdfs.fastdfs;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.*;
/**
* @ClassName: FasfDFSClient
* @Desc: FastDFS客户端
* @Author: liuhefei
* @Date: 2018/12/24 17:33
*/
public class FastDFSClient {
private static Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
//在类加载的时候读取相应的配置信息,并进行初始化。
static{
try{
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
ClientGlobal.init(filePath);
}catch (Exception e){
logger.error("FastDFS Client Init Fail!",e);
}
}
/**
* 文件上传
* 使用FastDFS提供的客户端storageClient来进行文件上传,最后将上传结果返回。
* @param file
* @return
*/
public static String[] upload(FastDFSFile file) {
logger.info("File Name: " + file.getName() + "File Length:" + file.getContent().length);
NameValuePair[] meta_list = new NameValuePair[1];
meta_list[0] = new NameValuePair("author", file.getAuthor());
long startTime = System.currentTimeMillis();
String[] uploadResults = null;
StorageClient storageClient=null;
try {
storageClient = getTrackerClient();
uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
} catch (IOException e) {
logger.error("IO Exception when uploadind the file:" + file.getName(), e);
} catch (Exception e) {
logger.error("Non IO Exception when uploadind the file:" + file.getName(), e);
}
logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");
if (uploadResults == null && storageClient!=null) {
logger.error("upload file fail, error code:" + storageClient.getErrorCode());
}
String groupName = uploadResults[0];
String remoteFileName = uploadResults[1];
logger.info("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);
return uploadResults;
}
/**
* 根据groupName和文件名获取文件信息。
* @param groupName 分组名
* @param remoteFileName
* @return
*/
public static FileInfo getFile(String groupName, String remoteFileName) {
try {
StorageClient storageClient = getTrackerClient();
return storageClient.get_file_info(groupName, remoteFileName);
} catch (IOException e) {
logger.error("IO Exception: Get File from Fast DFS failed", e);
} catch (Exception e) {
logger.error("Non IO Exception: Get File from Fast DFS failed", e);
}
return null;
}
/**
* 下载文件
* @param groupName
* @param remoteFileName
* @return
*/
public static InputStream downFile(String groupName, String remoteFileName) {
try {
StorageClient storageClient = getTrackerClient();
byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
InputStream ins = new ByteArrayInputStream(fileByte);
return ins;
} catch (IOException e) {
logger.error("IO Exception: Get File from Fast DFS failed", e);
} catch (Exception e) {
logger.error("Non IO Exception: Get File from Fast DFS failed", e);
}
return null;
}
/**
* 删除文件
* @param groupName
* @param remoteFileName
* @throws Exception
*/
public static void deleteFile(String groupName, String remoteFileName)
throws Exception {
StorageClient storageClient = getTrackerClient();
int i = storageClient.delete_file(groupName, remoteFileName);
logger.info("delete file successfully!!!" + i);
}
public static StorageServer[] getStoreStorages(String groupName)
throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
return trackerClient.getStoreStorages(trackerServer, groupName);
}
public static ServerInfo[] getFetchStorages(String groupName,
String remoteFileName) throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
}
public static String getTrackerUrl() throws IOException {
return "http://"+getTrackerServer().getInetSocketAddress().getHostString()+":"+ClientGlobal.getG_tracker_http_port()+"/";
}
private static StorageClient getTrackerClient() throws IOException {
TrackerServer trackerServer = getTrackerServer();
StorageClient storageClient = new StorageClient(trackerServer, null);
return storageClient;
}
private static TrackerServer getTrackerServer() throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
return trackerServer;
}
}(b)FastDFSFile.java
package com.lhf.springbootfastdfs.fastdfs;
/**
* @ClassName: FastDFSFile
* @Desc:
* @Author: liuhefei
* @Date: 2018/12/24 17:33
*/
public class FastDFSFile {
private String name;
private byte[] content;
private String ext;
private String md5;
private String author;
public FastDFSFile(String name, byte[] content, String ext, String height,
String width, String author) {
super();
this.name = name;
this.content = content;
this.ext = ext;
this.author = author;
}
public FastDFSFile(String name, byte[] content, String ext) {
super();
this.name = name;
this.content = content;
this.ext = ext;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
public String getExt() {
return ext;
}
public void setExt(String ext) {
this.ext = ext;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}(c)controller控制层UploadController.java:实现上传文件
package com.lhf.springbootfastdfs.controller;
import com.lhf.springbootfastdfs.fastdfs.FastDFSClient;
import com.lhf.springbootfastdfs.fastdfs.FastDFSFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName: UploadController
* @Desc:
* @Author: liuhefei
* @Date: 2018/12/24 17:34
*/
@Controller
public class UploadController {
private static Logger logger = LoggerFactory.getLogger(UploadController.class);
@GetMapping("/")
public String index(){
return "upload";
}
@PostMapping("/upload")
public String singleFileUpload(@RequestParam("file")MultipartFile file, RedirectAttributes redirectAttributes){
if(file.isEmpty()){
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadStatus";
}
try{
String path = saveFile(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded '" + file.getOriginalFilename() + "'");
redirectAttributes.addFlashAttribute("path", "file path url '" + path + "'");
}catch (Exception e){
logger.error("upload file failed", e);
}
return "redirect:/uploadStatus";
}
@GetMapping("/uploadStatus")
public String uploadStatus(){
return "uploadStatus";
}
/**
* 保存文件
* 从MultipartFile中读取文件信息,然后使用FastDFSClient将文件上传到FastDFS集群中。
* @param multipartFile
* @return
* @throws IOException
*/
public String saveFile(MultipartFile multipartFile) throws IOException {
String[] fileAbsolutePath={};
String fileName=multipartFile.getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
byte[] file_buff = null;
InputStream inputStream=multipartFile.getInputStream();
if(inputStream!=null){
int len1 = inputStream.available();
file_buff = new byte[len1];
inputStream.read(file_buff);
}
inputStream.close();
FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);
try {
fileAbsolutePath = FastDFSClient.upload(file); //upload to fastdfs
} catch (Exception e) {
logger.error("upload file Exception!",e);
}
if (fileAbsolutePath==null) {
logger.error("upload file failed,please upload again!");
}
String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
logger.info("path = {}", path);
return path;
}
}(d)前端页面:upload.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <h1>Spring Boot file upload example</h1> <form method="POST" action="/upload" enctype="multipart/form-data"> <input type="file" name="file" /><br/><br/> <input type="submit" value="Submit" /> </form> </body> </html>
实例效果如图:
图片上传成功,通过返回的地址即可查看!
项目地址:https://github.com/JavaCodeMood/springboot-fastdfs
分享就到这里,感谢诸君的支持!
共同学习,写下你的评论
评论加载中...
作者其他优质文章

